The Shortest Path in Nya Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1279 Accepted Submission(s): 286
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 <= 10 5) and C(1 <= C <= 10 3), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers l i (1 <= l i <= N), which is the layer of i th node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 4), 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 <= 10 5) and C(1 <= C <= 10 3), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers l i (1 <= l i <= N), which is the layer of i th node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 4), 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这题 ,就是一个最短路,但是在建图的过程是很难啊,主要是,不同层之间的关系,如果是直接建的话,复杂度,达到n*n,这样是不可接受的,所以,这题主要是拆点,把第0到第i-1层想象成点,这样,我们规过n+2*i为第i层入点,n+2*(i+1)是第i层出点,这样,我们就可以通过原点与这些想象的点想连,就可以在线性时间里,把图建好了!#include <iostream> #include <stdio.h> #include <vector> #include <string.h> #include <queue> using namespace std; #define typec int const typec inf =0x4f4f4f4f; #define E 1000500 #define V 300500 vector<int > vec[V]; typec cost[E],dist[V]; int e,pnt[E],nxt[E],head[V],prev[V],vis[V],num[V]; struct qnode { int v;typec c; qnode (int vv=0,typec cc=0):v(vv),c(cc){} bool operator <(const qnode & r)const {return c>r.c;} }; void dijkstra(int n,const int src){ qnode mv; int i,j,k,pre; priority_queue<qnode> que; vis[src]=1;dist[src]=0; que.push(qnode(src,0)); for(pre=src,i=1;i<n;i++){ for(j=head[pre];j!=-1;j=nxt[j]){ k=pnt[j]; if(vis[k]==0&& dist[pre]+cost[j]<dist[k]){ dist[k]=dist[pre]+cost[j]; que.push(qnode(pnt[j],dist[k])); prev[k]=pre; } } while(!que.empty()&&vis[que.top().v]==1){ que.pop(); } if(que.empty())break; mv=que.top();que.pop(); vis[pre=mv.v]=1; } } inline void addedge(int u,int v,typec c){ pnt[e]=v;cost[e]=c;nxt[e]=head[u];head[u]=e++; } int main() { int i,u,v,n,m,temp;typec c; int tcase,tt=1,s,ee; scanf("%d",&tcase); while(tcase--){ scanf("%d%d%d",&n,&m,&c); e=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(prev,-1,sizeof(prev)); int n3=3*n; for(i=0;i<n3;i++) vec[i].clear(); for(i=0;i<n;i++){ scanf("%d",&temp); temp--; addedge(n+2*temp+1,i,0); addedge(i,n+2*temp,0); } for(i=0;i<n3;i++)dist[i]=inf; for(i=0;i<n-1;i++) { addedge(n+2*i,n+2*(i+1)+1,c); addedge(n+2*(i+1),n+2*i+1,c); } for(i=0;i<m;i++){ scanf("%d%d%d",&s,&ee,&c); s--,ee--; addedge(s,ee,c); addedge(ee,s,c); } dijkstra(n3,0); if(dist[n-1]!=inf) printf("Case #%d: %d\n",tt++,dist[n-1]); else printf("Case #%d: -1\n",tt++); } return 0; }