http://acm.hdu.edu.cn/showproblem.php?pid=4725
The Shortest Path in Nya Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7869 Accepted Submission(s): 1766
Problem Description
This
is a very easy problem, your task is just calculate el camino mas corto
en un grafico, and just solo hay que cambiar un poco el algoritmo. If
you do not understand a word of this paragraph, just move on.
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.
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.
Input
The first line has a number T (T <= 20) , indicating the number of test cases.
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.
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.
Output
For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N.
If there are no solutions, output -1.
If there are no solutions, output -1.
Sample Input
2
3 3 3
1 3 2
1 2 1
2 3 1
1 3 3
3 3 3
1 3 2
1 2 2
2 3 2
1 3 4
Sample Output
Case #1: 2
Case #2: 3
Source
一开始无脑暴力建 N1*N2的图,后来超时后才发现,如果层数稀疏,点数密集的话建的边数上亿,肯定要超时的,我们想办法巧妙地建图。
把每一层看做是一个点,通过点->层->点的连接从而实现层与层的连接,可以少建许多边,但我第一次没考虑周到,让点与对应的层建立了双向边,这是致命的,,
因为每一层的点之间距离并非是0,这样构图的话每一层得点相互之间都能0距离显然是错误的。
考虑建单向边,让每一层向层上的点建一条0边,然后对于每个点,向与其相邻且存在的层建立一条权值为C的边,这样就符合了题意。
spfa和dij都写了感觉复杂度差不多,但是第一次建图错误时spfa提示TLE,dij返回WA不知道是否说明dij快点- -反正二者AC的时间差不大多
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 using namespace std; 6 #define inf 0x3f3f3f3f 7 inline int read() 8 { 9 int r=0; char c=getchar(); 10 while(!isdigit(c)) c=getchar(); 11 while(isdigit(c)) {r=r*10+c-'0';c=getchar();} 12 return r; 13 } 14 struct Edge 15 { 16 int to,w,next; 17 }e[600005]; 18 int cnt,first[200005]; 19 void add(int u,int v,int w) 20 { 21 e[cnt].to=v; 22 e[cnt].w=w; 23 e[cnt].next=first[u]; 24 first[u]=cnt++; 25 } 26 struct node 27 { 28 int u,w; 29 bool operator<(const node &x)const{ 30 return w>x.w; 31 } 32 }; 33 int d[200005]; 34 int dij(int N) 35 { 36 bool vis[200005]; 37 priority_queue<node>Q; 38 memset(vis,0,sizeof(vis)); 39 memset(d,inf,sizeof(d)); 40 d[1]=0; 41 Q.push(node{1,0}); 42 while(!Q.empty()){ 43 node t1=Q.top();Q.pop(); 44 int u=t1.u; 45 if(vis[u]) continue; 46 vis[u]=1; 47 if(u==N) break; 48 for(int i=first[u];i+1;i=e[i].next){ 49 Edge x=e[i]; 50 if(!vis[x.to]&&d[x.to]>d[u]+x.w){ 51 d[x.to]=d[u]+x.w; 52 Q.push(node{x.to,d[x.to]}); 53 } 54 } 55 } 56 return d[N]==inf?-1:d[N]; 57 } 58 int spfa(int N) 59 { 60 bool vis[200005]; 61 queue<int>Q; 62 memset(vis,0,sizeof(vis)); 63 memset(d,inf,sizeof(d)); 64 Q.push(1); 65 vis[1]=1; 66 d[1]=0; 67 while(!Q.empty()){ 68 int u=Q.front(); Q.pop(); 69 vis[u]=0; 70 for(int i=first[u];i+1;i=e[i].next){ 71 Edge x=e[i]; 72 if(d[x.to]>d[u]+x.w){ 73 d[x.to]=d[u]+x.w; 74 if(!vis[x.to]){ 75 Q.push(x.to); 76 } 77 } 78 } 79 } 80 return d[N]==inf?-1:d[N]; 81 } 82 int main() 83 { 84 //ios::sync_with_stdio(false); 85 int T,N,M,C,i,j,k=0; 86 int u,v,w,x[100005]; 87 bool layer[100005]; 88 #ifndef ONLINE_JUDGE 89 freopen("in.txt","r",stdin); 90 #endif 91 T=read(); 92 for(int cas=1;cas<=T;++cas) 93 { 94 cnt=0; 95 memset(first,-1,sizeof(first)); 96 memset(layer,0,sizeof(layer)); 97 cin>>N>>M>>C; 98 for(i=1;i<=N;++i) 99 { 100 x[i]=read(); 101 layer[x[i]]=1; 102 } 103 for(i=1;i<=N;++i) 104 { 105 add(x[i]+N,i,0); 106 add(i,x[i]+N,0); 107 if(x[i]>1&&layer[x[i]-1]) 108 add(i,x[i]+N-1,C); 109 if(x[i]<N&&layer[x[i]+1]) 110 add(i,x[i]+N+1,C); 111 } 112 while(M--){ 113 scanf("%d%d%d",&u,&v,&w); 114 add(u,v,w); 115 add(v,u,w); 116 } 117 printf("Case #%d: %d ",cas,dij(N)/*spfa(N)*/); 118 } 119 return 0; 120 }