HDU4725 The Shortest Path in Nya Graph(最短路分层)
题意:
给出一张无向图,和每个节点所在的层数,相邻层的节点之间可以通过固定的代价抵达,询问1到N的最短路径。
题解:
暴力建图肯定会爆栈,考虑拆点,每个层拆出一个中间点,所在层对应的中间点向每个点建单向边,每个点向上下相邻层的中间点建双向边。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<vector> using namespace std; const int maxn=7e5+100; const int inf=1e9; struct node { int u,v,w,next; }edge[maxn*2]; int head[maxn*2]; int tol; void addedge (int u,int v,int w) { edge[tol].u=u; edge[tol].v=v; edge[tol].w=w; edge[tol].next=head[u]; head[u]=tol++; } struct qnode { int v,w; bool operator < (const qnode &r) const { return w>r.w; } }; int d[maxn]; int visit[maxn]; void dijkstra (int s) { fill(visit,visit+maxn,0); fill(d,d+maxn,inf); d[s]=0; priority_queue<qnode> q; q.push({s,d[s]}); while (!q.empty()) { qnode now=q.top(); q.pop(); int u=now.v; if (visit[u]) continue; visit[u]=1; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if (!visit[v]&&d[u]+edge[i].w<d[v]) { d[v]=d[u]+edge[i].w; q.push({v,d[v]}); } } } } int main () { int T; scanf("%d",&T); for (int k=1;k<=T;k++) { int N,M,C; scanf("%d%d%d",&N,&M,&C); memset(head,-1,sizeof(head)); tol=0; for (int i=1;i<=N;i++) { int x; scanf("%d",&x); addedge(N+x,i,0); addedge(i,N+x+1,C); addedge(N+x+1,i,C); if (x>1) { addedge(i,N+x-1,C); addedge(N+x-1,i,C); } } for (int i=1;i<=M;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } dijkstra(1); if (d[N]==inf) d[N]=-1; printf("Case #%d: %d\n",k,d[N]); } }