D74 最短路 化层为点 Dijkstra 算法 HDU4725 The Shortest Path in Nya Graph
D74 最短路 化层为点 Dijkstra 算法 HDU4725 The Shortest Path in Nya Graph_哔哩哔哩_bilibili
Problem - HDU4725 The Shortest Path in Nya Graph
给 n 个点 m 条有权边的无向图,给出每个点所属的层,相邻的层之间有一条权值为 c 的边,求 1-n 的最短路。
思路
扩点:把每一层化为一个虚点。
扩边:
- 每层虚点向每层的实点连权值为 0 的单向边;
- 每个实点向相邻层虚点连权值为 c 的单向边。
这样虚点就架起了相邻层之间的一座代价为 c 的桥。
然后,实点之间连接 m 条双向边。跑一遍 Dijkstra 求最短路。
图中,黑点为实点,黑边为双向边;红点为虚点,红边为单向边。

相关板子:
D02【模板】最短路 Dijkstra 算法 P4779 单源最短路径 - 董晓 - 博客园
// 最短路 Dijkstra 算法 O(mlogn) #include<bits/stdc++.h> #define pii pair<int,int> using namespace std; const int N=100010,inf=0x3f3f3f3f; int idx,h[N*2],to[N*5],ne[N*5],w[N*5]; void add(int x,int y,int z){ to[++idx]=y;w[idx]=z;ne[idx]=h[x];h[x]=idx; } int n,m,c; int d[N*2],vis[N*2]; void dijkstra(){ for(int i=1;i<=2*n;i++)d[i]=inf,vis[i]=0; d[1]=0; priority_queue<pii,vector<pii>,greater<pii>> q; q.emplace(0,1); while(!q.empty()){ int u=q.top().second;q.pop(); if(vis[u])continue; vis[u]=1; for(int i=h[u];i;i=ne[i]){ int v=to[i]; if(d[v]>d[u]+w[i]){ d[v]=d[u]+w[i]; q.emplace(d[v],v); } } } } int main(){ int T,cas=0; scanf("%d",&T); while(T--){ idx=0; memset(h,0,sizeof(h)); scanf("%d%d%d",&n,&m,&c); for(int i=1,x;i<=n;i++){ scanf("%d",&x); //实点i在第x层 add(n+x,i,0); //第x层虚点向实点i连权值为0的单向边 if(x>1) add(i,n+(x-1),c); if(x<n) add(i,n+x+1,c); //实点i向相邻层虚点连权值为c的单向边 } for(int i=1,u,v,w;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); //实点之间连双向边 } dijkstra(); printf("Case #%d: ",++cas); if(d[n]==inf) printf("-1\n"); else printf("%d\n",d[n]); } }
浙公网安备 33010602011771号