hdu 4725 The Shortest Path in Nya Graph

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.
 

 

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.
 

 

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.
 

 

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

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 #define N 100005
  6 #define inf 0x3f3f3f3f
  7 using namespace std;
  8 int n,m,C;
  9 struct Edges
 10 {
 11     int x,y,w,next;
 12 };
 13 struct HeapNode
 14 {
 15     int d;
 16     int u;
 17     bool operator < (const HeapNode& rhs) const{
 18         return d>rhs.d;
 19     }
 20 };
 21 priority_queue<HeapNode>Q;
 22 Edges e[N*10];
 23 int head[3*N];
 24 int dis[3*N];
 25 bool done[3*N];
 26 int k;
 27 
 28 void AddEdge(int x,int y,int w)
 29 {
 30     e[k].x=x,e[k].y=y,e[k].w=w,e[k].next=head[x],head[x]=k++;
 31 }
 32 int DJ()
 33 {
 34     memset(dis,inf,sizeof(dis));
 35     memset(done,false,sizeof(done));
 36     dis[1]=0;
 37     HeapNode p;
 38     p.d=dis[1];
 39     p.u=1;
 40     Q.push(p);
 41     while(!Q.empty())
 42     {
 43         HeapNode x = Q.top();
 44         Q.pop();
 45         int u=x.u;
 46         if(done[u])
 47         continue;
 48         done[u]=true;
 49         for(int i=head[u];i!=-1;i=e[i].next)
 50         {
 51             int y=e[i].y;
 52             int w=e[i].w;
 53             if(dis[u]+w<dis[y])
 54             {
 55                 dis[y]=dis[u]+w;
 56                 HeapNode temp;
 57                 temp.d=dis[y];
 58                 temp.u=y;
 59                 Q.push(temp);
 60             }
 61         }
 62     }
 63     return dis[n];
 64 }
 65 
 66 int main()
 67 {
 68     int t;
 69     scanf("%d",&t);
 70     int cas=1;
 71     while(t--)
 72     {
 73         scanf("%d%d%d",&n,&m,&C);
 74         memset(head,-1,sizeof(head));
 75         k=0;
 76         for(int i=1;i<=n;i++)
 77         {
 78             int num;
 79             scanf("%d",&num);
 80             AddEdge(i,n+2*num-1,0);
 81             AddEdge(n+2*num,i,0);
 82         }
 83         for(int i=1;i<n;i++)
 84         {
 85             AddEdge(n+2*i-1,n+2*(i+1),C);
 86             AddEdge(n+2*(i+1)-1,n+2*i,C);
 87         }
 88         for(int i=0;i<m;i++)
 89         {
 90             int x,y,z;
 91             scanf("%d%d%d",&x,&y,&z);
 92             AddEdge(x,y,z);
 93             AddEdge(y,x,z);
 94         }
 95         int res=DJ();
 96         if(res==inf)
 97         {
 98             printf("Case #%d: -1\n",cas++);
 99         }
100         else
101         {
102             printf("Case #%d: %d\n",cas++,res);
103         }
104     }
105     return 0;
106 }
View Code

最短路问题,主要考的是构图的思想;

思路:

将每一层拆分成两个点,例如,第一层分成n+1即(n+2*i-1)和n+2(n+2*i);总共3*n个点;

也就是第i层分成n+2*i-1和n+2*i;规定n+2*i-1始终作为入边,n+2*i始终作为出边;

如果某个点属于第i层,就连边i->n+2*i-1,n+2*i->i,权值为0;

然后根据题意,相邻的层次连边,权值为C,n+2*i-1->n+2*(i+1)和n+2*(i+1)-1->n+2*i;

然后跟着输入的边构图;

基本上这题的图构好之后,跑一边迪杰斯特拉+优先队列的模板,就能解决此题;



 

posted @ 2013-09-11 20:56  欧阳生朵  阅读(786)  评论(0编辑  收藏  举报