HDU - 4725 The Shortest Path in Nya Graph 【拆点 + dijkstra】
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.
InputThe 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.OutputFor 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
这题的难点是层数的处理,有两种处理方法。
一种是仔细想可以想到的,用vector把每层的点存下来,在djkstra松弛操作的同时,对当前点的相邻两层点全部松弛一遍(具体看代码)。
第二种应该是正解,就是拆点。其实上一种也相当于拆点,只不过拆很暴力,不够彻底。
我们可以把层当做一个新的点,在该层的点到该层的距离为0,该层到相邻层的距离为c。但因为同层的点不一定相互联通,所以要把一个层分为两个点,一个入口点,一个出口点,入口点和出口点之间不联通。
法一ac代码:
1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 #include <cmath>
6 #include <queue>
7 using namespace std;
8 typedef long long ll;
9 const int inf = 0x3f3f3f3f;
10 const int maxn = 1e5 + 10;
11 int n, m, c;
12 int pos[maxn];
13 vector<int> laye[maxn];
14 int head[maxn];
15 int d[maxn];
16 bool vis[maxn];
17 bool visi[maxn];
18 struct edge{
19 int to, nex, cost;
20 }eg[2 * maxn];
21 int cnt = 0;
22 inline void add(int u,int v,int cost) {
23 eg[cnt].to = v;
24 eg[cnt].nex = head[u];
25 eg[cnt].cost = cost;
26 head[u] = cnt++;
27 }
28 struct Rule {
29 bool operator () (int &a,int &b) const {
30 return d[a] > d[b];
31 }
32 };
33 inline void dijkstra(int s) {
34 memset(vis, 0, sizeof(vis));
35 memset(d, inf, sizeof(d));
36 priority_queue<int, vector<int>, Rule> q;
37 d[s] = 0;
38 q.push(s);
39 while(!q.empty()) {
40 int u = q.top(); q.pop();
41 for(int k = head[u]; ~k; k = eg[k].nex) {
42 int v = eg[k].to;
43 if(d[v] > d[u] + eg[k].cost) {
44 // printf("%d %d %d\n", u, v,eg[k].cost);
45 d[v] = d[u] + eg[k].cost;
46 q.push(v);
47 }
48 }
49 if(pos[u] < n && !vis[pos[u]+ 1]) {
50 vis[pos[u] + 1] = true; //注意标记层数,不然会超时
51 for(int i = 0; i < laye[pos[u] + 1].size(); ++i) {
52 int v = laye[pos[u] + 1][i];
53 if(d[v] > d[u] + c) {
54 // printf("%d %d %d\n", u, v,c);
55 d[v] = d[u] + c;
56 q.push(v);
57
58 }
59 }
60 }
61 if(pos[u] > 1 && !vis[pos[u] - 1]) {
62 vis[pos[u] - 1] = true;
63 for(int i = 0; i < laye[pos[u] - 1].size(); ++i) {
64 int v = laye[pos[u] - 1][i];
65 if(d[v] > d[u] + c) {
66 // printf("%d %d %d\n", u, v,c);
67 d[v] = d[u] + c;
68 q.push(v);
69
70 }
71 }
72 }
73 }
74 }
75 int main()
76 {
77 int t;
78 scanf("%d", &t);
79 for(int cas = 1; cas <= t; ++cas) {
80 cnt = 0;
81 memset(head, -1, sizeof(head));
82 memset(pos, 0, sizeof(pos));
83
84 scanf("%d %d %d", &n, &m, &c);
85 int u, v, cost;
86 for(int i = 1; i <= n; ++i) {
87 scanf("%d", &u);
88 pos[i] = u;
89 laye[u].push_back(i);
90 }
91 for(int i =0; i < m; ++i) {
92 scanf("%d %d %d", &u, &v, &cost);
93 add(u, v, cost);
94 add(v, u, cost);
95 }
96
97 dijkstra(1);
98 if(d[n] == inf || n == 0)
99 printf("Case #%d: -1\n", cas);
100 else
101 printf("Case #%d: %d\n", cas, d[n]);
102 for(int i = 1; i <= n; ++i) laye[i].clear();
103 }
104 return 0;
105 }
法二代码:
1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 #include <cmath>
6 #include <queue>
7 using namespace std;
8 typedef long long ll;
9 const int inf = 0x3f3f3f3f;
10 const int maxn = 5 * 1e5;
11 int n, m, c;
12 int pos[maxn];
13 vector<int> laye[maxn];
14 int head[maxn];
15 int d[maxn];
16 bool vis[maxn];
17 struct edge{
18 int to, nex, cost;
19 }eg[maxn];
20 int cnt = 0;
21 void add(int u,int v,int cost) {
22 eg[cnt].to = v;
23 eg[cnt].nex = head[u];
24 eg[cnt].cost = cost;
25 head[u] = cnt++;
26 }
27 struct Rule {
28 bool operator () (int a,int b) const {
29 return d[a] > d[b];
30 }
31 };
32 void dijkstra(int s) {
33 memset(d, inf, sizeof(d));
34 priority_queue<int, vector<int>, Rule> q;
35 d[s] = 0;
36 q.push(s);
37 while(!q.empty()) {
38 int u = q.top(); q.pop();
39 for(int k = head[u]; k != -1; k = eg[k].nex) {
40 int v = eg[k].to;
41 if(d[v] > d[u] + eg[k].cost) {
42 // printf("%d %d %d\n", u, v,eg[k].cost);
43 d[v] = d[u] + eg[k].cost;
44 q.push(v);
45 }
46
47 }
48 }
49 }
50 int main()
51 {
52 int t;
53 scanf("%d", &t);
54 for(int cas = 1; cas <= t; ++cas) {
55
56 cnt = 0;
57 memset(d, inf, sizeof(d));
58 memset(head, -1, sizeof(head));
59 memset(pos, 0, sizeof(pos));
60 scanf("%d %d %d", &n, &m, &c);
61 int u, v, cost;
62 for(int i = 1; i <= n; ++i) {
63 scanf("%d", &u);
64 pos[i] = u;
65 add(i, n + 2 * u - 1, 0);//层内的点到该层距离为0
66 add(n + 2 * u, i, 0);
67 vis[u] = true;
68 }
69 for(int i = 1; i < n; ++i) {
70 if(vis[i] && vis[i + 1]) {//这个似乎不加也行
71 add(n + 2 * i - 1, n + 2 * (i + 1), c);//相邻层之间的距离为c
72 add(n + 2 * (i + 1) - 1, n + 2 * i, c);
73 }
74 }
75 for(int i =0; i < m; ++i) {
76 scanf("%d %d %d", &u, &v, &cost);
77 add(u, v, cost);
78 add(v, u, cost);
79 }
80
81 dijkstra(1);
82 if(d[n] == inf || n == 0)
83 printf("Case #%d: -1\n", cas);
84 else
85 printf("Case #%d: %d\n", cas, d[n]);
86 }
87 return 0;
88 }
HDU - 4725 The Shortest Path in Nya Graph 【拆点 + dijkstra】的更多相关文章
- HDU - 4725 The Shortest Path in Nya Graph(拆点+Dijkstra)
题意:N个点,每个点有一个层号L,相邻的两层 Li 与 Li+1 之间的距离为C.另外给出M条无向边,求从点1到点N的最短路. 分析:同一层之间的两点距离并不是0,这是一个小坑.依次把相邻两层的所有点 ...
- Hdu 4725 The Shortest Path in Nya Graph (spfa)
题目链接: Hdu 4725 The Shortest Path in Nya Graph 题目描述: 有n个点,m条边,每经过路i需要wi元.并且每一个点都有自己所在的层.一个点都乡里的层需要花费c ...
- HDU 4725 The Shortest Path in Nya Graph [构造 + 最短路]
HDU - 4725 The Shortest Path in Nya Graph http://acm.hdu.edu.cn/showproblem.php?pid=4725 This is a v ...
- HDU 4725 The Shortest Path in Nya Graph
he Shortest Path in Nya Graph Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged o ...
- 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 ...
- 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 ...
- 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 ...
- (中等) HDU 4725 The Shortest Path in Nya Graph,Dijkstra+加点。
Description This is a very easy problem, your task is just calculate el camino mas corto en un grafi ...
- HDU 4725 The Shortest Path in Nya Graph(最短路径)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description This is a very easy problem, your task is just calculate el camino mas corto en un grafi ...
- HDU 4725 The Shortest Path in Nya Graph (最短路 )
This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just ...
随机推荐
- eCATT使用前的配置
如果想在SAP中使用eCATT,必须做一下相关的配置才行,下面简单介绍这几步:1.SM30,输入表T000,然后点击维护,或者是进入事物SCC4,进入对应的clint属性编辑视图下,将CATT and ...
- Linux学习安装
Linux学习安装 服务器指的是网络中能对其他机器提供某些服务的计算机系统,相对普通PC, 服务器指的是高性能计算机,稳定性.安全性要求更高 linux安装学习 1.虚拟机 一台硬件的机器 安装vmw ...
- django 组件 自定义过滤器 自定义标签 静态文件配置
组件 将一些功能标签写在一个html文件里,这个文件作为一个组件,如果那个文件需要就直接拿过来使用即可: 这是title.html文件,写了一个导航栏,作为一个公用的组件 <div style= ...
- ichartjs测试dome分享
效果如下: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> ...
- postgres多知识点综合案例
使用到的知识点: 1.使用with临时存储sql语句,格式[with as xxx(), as xxx2() ]以减少代码: 2.使用round()取小数点后几位: 3.使用to_char()将时间格 ...
- 如何在Redis中实现事务
如何在Redis中实现事务 - 微店技术团队 - SegmentFault 思否 https://segmentfault.com/a/1190000007429197
- 【Python网络编程】epoll用法
epoll发展进程 此处添加一下select.poll历程及其优缺点 原理 使用步骤 Create an epoll object--创建1个epoll对象 Tell the epoll object ...
- 使用“2”个参数调用“SetData”时发生异常:“程序集“
使用"2"个参数调用"SetData"时发生异常:"程序集"Microsoft.VisualStudio.ProjectSystem.VS. ...
- 洛谷P2145
Description 给定一串数字,每个数字代表一种颜色 你可以向这个数字序列里加任意数字,每加一个视为一次操作 当你加入的数字和与它相连的同种数字不少于三个时,他们就会消除 消除后序列的两端自动靠 ...
- loj10004智力大冲浪
题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m 元.先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则 ...