Total Submission(s): 193 Accepted Submission(s): 38
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
Help us calculate the shortest path from node 1 to node N.
For each test case, first line has three numbers N, M (0 <= N, M <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), which means there is an extra edge, connecting a pair of node u and v, with cost w.
If there are no solutions, output -1.
#include<cstring> #include<cstdio> #include<iostream> #include<queue> #include<vector> #include<algorithm> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) #define LL int using namespace std; const int mm=5e5+9; const LL oo=1e9; int id[mm],to[mm]; bool vis[mm]; class Edge { public: int v,w,next; } e[mm+mm]; class Dot { public: int dis,id; Dot(int a,int b){dis=a;id=b;} Dot(){} bool operator<(const Dot&x)const { if(dis!=x.dis)return dis>x.dis; return id<x.id; } } bel[mm]; int head[mm],edge; int N,M,C,KN; void data() { clr(head,-1); edge=0; } void add(int u,int v,int w) { e[edge].v=v; e[edge].w=w; e[edge].next=head[u]; head[u]=edge++; } LL dis[mm]; LL spfa(int u) { FOR(i,0,KN)dis[i]=oo,vis[i]=0; dis[u]=0; priority_queue<Dot>Q; Q.push(Dot(0,u)); Dot uu;int v; while(!Q.empty()) { uu=Q.top(); Q.pop(); u=uu.id; if(vis[u])continue; vis[u]=1; for(int i=head[u]; ~i; i=e[i].next) { v=e[i].v; if(!vis[v]&&dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; Q.push(Dot(dis[v],v)); } } } return dis[N]; } int main() { int cas,a,b,c,u; while(~scanf("%d",&cas)) FOR(ca,1,cas) { data(); scanf("%d%d%d",&N,&M,&C); for(int i = 1; i <= N; i++) { scanf("%d",&u); add(i,N + 2*u - 1,0);///2u-1当出边点 add(N + 2*u ,i,0);///2u当入边点 } for(int i = 1; i < N; i++)///每一层的出边连下一层入边 { add(N + 2*i-1,N + 2*(i+1),C); add(N + 2*(i+1)-1,N + 2*i,C); } FOR(i,1,M) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } KN=3*N; printf("Case #%d: ",ca); if(N==1) { printf("0\n"); } LL ans=spfa(1); if(ans>=oo) ans=-1; printf("%d\n",ans); } }