HDU 4725 The Shortest Path in Nya Graph (最短路)

The Shortest Path in Nya Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 37    Accepted Submission(s): 6


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 <= 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.
 

 

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
 

 

Recommend
zhuyuanchen520
 

 

最短路。

主要是建图。

N个点,然后有N层,要假如2*N个点。

总共是3*N个点。

 

点1~N就是对应的实际的点1~N.  要求的就是1到N的最短路。

 

然后点N+1 ~ 3*N 是N层拆出出来的点。

第i层,入边到N+2*i-1, 出边从N+2*i 出来。(1<= i <= N)

 

N + 2*i    到  N + 2*(i+1)-1 加边长度为C. 表示从第i层到第j层。

N + 2*(i+1) 到 N + 2*i - 1 加边长度为C,表示第i+1层到第j层。

 

如果点i属于第u层,那么加边 i -> N + 2*u -1         N + 2*u ->i  长度都为0

 

然后用优先队列优化的Dijkstra就可以搞出最短路了

 

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013-9-11 12:30:12
  4 File Name     :2013-9-11\1010.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 /*
 22  * 使用优先队列优化Dijkstra算法
 23  * 复杂度O(ElogE)
 24  * 注意对vector<Edge>E[MAXN]进行初始化后加边
 25  */
 26 const int INF=0x3f3f3f3f;
 27 const int MAXN=1000010;
 28 struct qnode
 29 {
 30     int v;
 31     int c;
 32     qnode(int _v=0,int _c=0):v(_v),c(_c){}
 33     bool operator <(const qnode &r)const
 34     {
 35         return c>r.c;
 36     }
 37 };
 38 struct Edge
 39 {
 40     int v,cost;
 41     Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
 42 };
 43 vector<Edge>E[MAXN];
 44 bool vis[MAXN];
 45 int dist[MAXN];
 46 void Dijkstra(int n,int start)//点的编号从1开始
 47 {
 48     memset(vis,false,sizeof(vis));
 49     for(int i=1;i<=n;i++)dist[i]=INF;
 50     priority_queue<qnode>que;
 51     while(!que.empty())que.pop();
 52     dist[start]=0;
 53     que.push(qnode(start,0));
 54     qnode tmp;
 55     while(!que.empty())
 56     {
 57         tmp=que.top();
 58         que.pop();
 59         int u=tmp.v;
 60         if(vis[u])continue;
 61         vis[u]=true;
 62         for(int i=0;i<E[u].size();i++)
 63         {
 64             int v=E[tmp.v][i].v;
 65             int cost=E[u][i].cost;
 66             if(!vis[v]&&dist[v]>dist[u]+cost)
 67             {
 68                 dist[v]=dist[u]+cost;
 69                 que.push(qnode(v,dist[v]));
 70             }
 71         }
 72     }
 73 }
 74 void addedge(int u,int v,int w)
 75 {
 76     E[u].push_back(Edge(v,w));
 77 }
 78 
 79 int main()
 80 {
 81     //freopen("in.txt","r",stdin);
 82     //freopen("out.txt","w",stdout);
 83     int T;
 84     int N,M,C;
 85     scanf("%d",&T);
 86     int iCase = 0;
 87     while(T--)
 88     {
 89         scanf("%d%d%d",&N,&M,&C);
 90         for(int i = 1;i <= 3*N;i++) E[i].clear();
 91         int u,v,w;
 92         for(int i = 1;i <= N;i++)
 93         {
 94             scanf("%d",&u);
 95             addedge(i,N + 2*u - 1,0);
 96             addedge(N + 2*u ,i,0);
 97 
 98         }
 99         for(int i = 1;i < N;i++)
100         {
101             addedge(N + 2*i-1,N + 2*(i+1),C);
102             addedge(N + 2*(i+1)-1,N + 2*i,C);
103         }
104         while(M--)
105         {
106             scanf("%d%d%d",&u,&v,&w);
107             addedge(u,v,w);
108             addedge(v,u,w);
109         }
110         Dijkstra(3*N,1);
111         iCase++;
112         if(dist[N] == INF)dist[N] = -1;
113         printf("Case #%d: %d\n",iCase,dist[N]);
114 
115     }
116     return 0;
117 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值