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 ...
随机推荐
- 1.5V转5V的最少电路的芯片电路图
PW5100满足1.5V转5V的很简洁芯片电路,同时达到了最少的元件即可组成DC-DC电路1.5V转5V的升压转换器系统. PW5100在1.5V转5V输出无负载时,输入效率电流极低,典型值10uA. ...
- 镍氢可充电电池2.4V转3.3V,2V转3.3V稳压供电输出电路图
PW5100可以实现2.4V转3.3V,2V转3.3V的稳压电源电路,输出电流500MA.静态电流10uA,SOT23-5封装.输出纹波低,轻载性能高(轻载电感推荐6.8UH-10UH). PW510 ...
- 同一份数据,Redis为什么要存两次
前言 在 Redis 中,有一种数据类型,当在存储的时候会同时采用两种数据结构来进行分别存储,那么 Redis 为什么要这么做呢?这么做会造成同一份数据占用两倍空间吗? 五种基本类型之集合对象 Red ...
- mysql半同步复制跟无损半同步区别
mysql半同步复制跟无损半同步复制的区别: 无损复制其实就是对semi sync增加了rpl_semi_sync_master_wait_point参数,来控制半同步模式下主库在返回给会话事务成功之 ...
- Spring Security,没有看起来那么复杂(附源码)
权限管理是每个项目必备的功能,只是各自要求的复杂程度不同,简单的项目可能一个 Filter 或 Interceptor 就解决了,复杂一点的就可能会引入安全框架,如 Shiro, Spring Sec ...
- 数字化转型中企业真正困惑-传统IT架构如何改造和全面上云
对数字化转型,整体来看大部分人相对关心问题主要还是集中在以下两个方面. 企业传统的IT架构如何如何微服务改造,演进发展 企业传统IT如何全面上云和实施云原生 以上两点实际都包括一个关键点,即企业当前内 ...
- 前端面试之HTTP
前端面试之HTTP的基本性质 1 HTTP代理 在浏览器和服务器之间,有许多计算机和其他设备转发了HTTP消息.简而言之,他们中间的部分就是代理! 代理的作用 缓存(可以是公开的也可以是私有的,像浏览 ...
- Linux系统设置 SSH 通过密钥登录
我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器.但是,一般的密码方式登录,容易有密码被暴力破解的问题.所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者 ...
- 每天学一点 Vue3(一) CND方式的安装以及简单使用
简介 感觉vue3的新特性很舒服,这样才是写软件的感觉嘛.打算用Vue实现自己的一些想法. Vue3还有几个必备库,比如Vue-Router(负责路由导航).Vuex(状态管理.组件间通信),还有第三 ...
- MySQL高可用HA——keepalived配置
0. Keepalived介绍 Keepalived是基于VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)协议的一款高可用软件.Keepaili ...