最短路练习

0. Til the Cows Come Home  POJ - 2387

完美的模板题

 1 //#include<Windows.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<queue>
 7 using namespace std;
 8 const int MAX_V = 10005;
 9 const int MAX_E = 20010;
10 const int inf = 0x3f3f3f3f;
11
12 struct ENode
13 {
14     int to;
15     int Next;
16     int w;
17 };
18 ENode Edegs[MAX_E];
19 int Head[MAX_V];
20 int Dis[MAX_V];
21 int tnt;
22 void Add_ENode(int u, int v, int w)
23 {
24     ++tnt;
25     Edegs[tnt].to = v;
26     Edegs[tnt].w = w;
27     Edegs[tnt].Next = Head[u];
28     Head[u] = tnt;
29     ++tnt;
30     Edegs[tnt].to = u;
31     Edegs[tnt].w = w;
32     Edegs[tnt].Next = Head[v];
33     Head[v] = tnt;
34 }
35 struct cmpx
36 {
37     bool operator () (int &a, int &b) const
38     {
39         return Dis[a] - Dis[b] > 0;
40     }
41 };
42
43 void Dijkstra(int x)
44 {
45     priority_queue<int, vector<int>, cmpx> q;
46     memset(Dis, inf, sizeof(Dis));
47     Dis[x] = 0;
48     q.push(x);
49     while (!q.empty())
50     {
51         int u = q.top();
52         q.pop();
53         for (int k = Head[u]; k != -1; k= Edegs[k].Next)
54         {
55             int v = Edegs[k].to;
56             if (Dis[v] > Dis[u] + Edegs[k].w)
57             {
58                 Dis[v] = Dis[u] + Edegs[k].w;
59                 q.push(v);
60             }
61         }
62     }
63 }
64
65 int main()
66 {
67     int t, n;
68     cin >> t >> n;
69     tnt = -1;
70     int a, b, w;
71     memset(Head, -1, sizeof(Head));
72     for (int i = 0; i < t; i++)
73     {
74         cin >> a >> b >> w;
75         Add_ENode(a, b, w);
76     }
77     Dijkstra(1);
78     cout << Dis[n] << endl;
79 //    system("pause");
80     return 0;
81 }

View Code

1. Frogger POJ - 2253

青蛙和石头。在池塘里有2只青蛙和n块石头,石头之间有一定距离,现在一只(腿短的)青蛙想要去找另一只青蛙yuehui;给出n块石头的坐标,1号为男主青蛙所在的石头,二号为目标石头。他想尽可能的省力,每次都跳的尽量短。问它在所有可行路径中单次跳跃需要的最长距离的最小值是多少?

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cmath>
 7 using namespace std;
 8 const int MAX_V= 210;
 9 const double inf= 99999999999999999.0;
10 typedef pair<double, double> _pair;
11 _pair rock[MAX_V];
12 double get_dis(_pair a, _pair b)
13 {
14     return sqrt(((a.first- b.first)* (a.first- b.first) )+ ((a.second- b.second)* (a.second- b.second) ) );
15 }
16 double Dis[MAX_V];
17 struct cmpx
18 {
19     bool operator() (int &a, int &b) const
20     {
21         return Dis[a]- Dis[b]> 0;
22     }
23 };
24 int Front[MAX_V];
25 void Dijkstra(int n)
26 {
27     priority_queue<int, vector<int>, cmpx> q;
28     fill(Dis, Dis+ n+ 1, inf);
29     //for(int i= 1; i<= n; i ++) printf("%f\n", Dis[2]);
30     Dis[1]= 0;
31     Front[1]= -1;
32     q.push(1);
33     while (! q.empty() )
34     {
35         int u= q.top();
36         q.pop();
37         for (int i= 2; i<= n; i ++)
38         {
39             if (i== u) continue;
40             double detmp= get_dis(rock[u], rock[i]);
41             //printf("%f---%f---%f\n", Dis[u], detmp, Dis[i]);
42             if (Dis[i]> Dis[u]&& Dis[i]> detmp)
43             {
44                 Dis[i]= max(Dis[u], detmp);
45                 Front[i]= u;
46                 q.push(i);
47             }
48             //printf("%f\n", Dis[i]);
49         }
50     }
51 }
52 int main()
53 {
54     int n;
55     int t= 0;
56     while (cin >> n)
57     {
58         ++ t;
59         if (n== 0) break;
60         for (int i= 1; i<= n; i ++)
61         {
62             cin >> rock[i].first >> rock[i].second;
63         }
64         //for(int i= 2; i<= n; i ++) printf("%f\n", get_dis(rock[1], rock[i]));
65         Dijkstra(n);
66         printf("Scenario #%d\n",t);
67         printf("Frog Distance = %.3f\n\n", Dis[2]);
68         double ans= -1.0;
69         /*for (int c= n; c!= 1; c= Front[c])
70         {
71             double cnp= get_dis(rock[c], rock[Front[c]]);
72             ans= max(ans, cnp);
73         }
74         printf("Frog Distance = %.3f\n\n", ans);*/
75     }
76     return 0;
77 }

View Code

2. Heavy Transportation POJ - 1797

城市中有N个路口,M个街道,每条街道都有最大承重限制;现在我们想要驾车从1号路口到N号路口,那么运输车所允许的最大重量是多少?

(不知道为什么老是PE,懒得改了)

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 using namespace std;
 7 const int maxv= 100010;
 8 const int maxe= 2100010;
 9 const int inf= 0x3f3f3f3f;
10
11 struct ENode
12 {
13     int to;
14     int w;
15     int Next;
16 };
17 ENode edegs[maxe];
18 int Head[maxv], tnt;
19 void init()
20 {
21     memset(Head, -1, sizeof(Head));
22     tnt= -1;
23 }
24 void Add_ENode(int a, int b, int w)
25 {
26     ++ tnt;
27     edegs[tnt].to= b;
28     edegs[tnt].w= w;
29     edegs[tnt].Next= Head[a];
30     Head[a]= tnt;
31     ++ tnt;
32     edegs[tnt].to= a;
33     edegs[tnt].w= w;
34     edegs[tnt].Next= Head[b];
35     Head[b]= tnt;
36 }
37
38 int dis[maxv];
39 struct cmpx
40 {
41     bool operator() (int &a, int &b) const
42     {
43         return dis[a]- dis[b]< 0;
44     }
45 };
46 void Dijkstra(int x)
47 {
48     priority_queue<int, vector<int>, cmpx> q;
49     memset(dis, 0, sizeof(dis));
50     dis[x]= inf;
51     q.push(x);
52
53     while (! q.empty())
54     {
55         int u= q.top();
56         q.pop();
57         for (int k= Head[u]; k!= -1; k= edegs[k].Next)
58         {
59             int v= edegs[k].to;
60             if (dis[v]< min(dis[u], edegs[k].w))
61             {
62                 dis[v]= min(dis[u], edegs[k].w);
63                 q.push(v);
64             }
65         }
66     }
67 }
68
69 int main()
70 {
71     int t, Case= 0;
72     int n, m;
73     scanf("%d", &t);
74     while (t --)
75     {
76         ++ Case;
77         scanf("%d %d", &n, &m);
78         init();
79         int a, b, w;
80         for (int i= 0; i< m; i ++)
81         {
82             scanf("%d %d %d", &a, &b, &w);
83             Add_ENode(a, b, w);
84         }
85         Dijkstra(1);
86         printf("Scenario #%d:\n%d\n", Case, dis[n]);
87     }
88     return 0;
89 }

View Code

3. Travel (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M)  /**计蒜客复现赛:点这里*/

星系中有n 个星球,编号从1 到N。星球之间有M个隧道相连,每个隧道都有一个长度。你有一个航天器,航天器有两个属性:传输距离d 和传输次数e 。航天器只能通过短于或等于其传输距离的通道;如果传输次数耗尽,则无法再使用航天器。航天器具有等级,lv0的航天器d 和e 都等于0,你可以给你的航天器升级,每次升级都会消耗c 点花费,给你的航天器提升dx和 ex点属性。现在,告诉你n,m,m条通道的信息,还有给你的航天器升级时的c,dx,ex。

Q: 你能求出从1 到N 的最小花费吗?

A: 把原本记录到达此点最短距离的Dis[] 变成 记录到达此点所需要飞行器最低等级的Dis_Level[],这样剩下的就是普通的Dijkstra了。

 1 #include<algorithm>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 const int MAX_V= 100010;
 7 const int MAX_E= 400010;
 8 const int inf= 0x3f3f3f3f;
 9
10 struct ENode
11 {
12     int to;
13     int w;
14     int Next;
15 };
16 ENode edegs[MAX_E];
17 int Head[MAX_V], tnt;
18 void Add_ENode(int a, int b, int w)
19 {
20     edegs[++ tnt].to= b;
21     edegs[tnt].w= w;
22     edegs[tnt].Next= Head[a];
23     Head[a]= tnt;
24     edegs[++ tnt].to= a;
25     edegs[tnt].w= w;
26     edegs[tnt].Next= Head[b];
27     Head[b]= tnt;
28 }
29
30 int Dis_Level[MAX_V];  //到每个点,所需要的飞船最小等级;
31 int deep[MAX_V];  //每个点bfs 的深度;
32 struct cmpx
33 {
34     bool operator() (int &a, int &b) const
35     {
36         return Dis_Level[a]- Dis_Level[b]> 0;
37     }
38 };
39 void Dijkstra(int x, int _dis, int _cost)
40 {
41     /*x为起点, _dis是每次升级提升的传送距离, _cost是升级提升的传送次数;*/
42     memset(Dis_Level, inf, sizeof(Dis_Level));
43     memset(deep, inf, sizeof(deep));
44     priority_queue<int, vector<int>, cmpx> q;
45     Dis_Level[x]= 0; //起点的飞行器等级为0;
46     deep[x]= 0;  //起点深度为0;
47     q.push(x);
48     while (! q.empty())
49     {
50         int u= q.top();
51         q.pop();
52         for (int k= Head[u]; k!= -1; k= edegs[k].Next)
53         {
54             int v= edegs[k].to;
55             int lev_tmp= Dis_Level[u];
56             while (lev_tmp* _dis< edegs[k].w|| lev_tmp* _cost< deep[u]+ 1)
57             {
58                 /*若当前的飞行器等级不能穿越此隧道,或传送次数已用完,则升级飞行器一次;*/
59                 lev_tmp ++;
60             }
61             if (lev_tmp< Dis_Level[v])
62             {
63                 /*如果此时的飞行器等级小与之前到达点v 的飞行器等级,则更新Dis_Level[v]*/
64                 Dis_Level[v]= lev_tmp;
65                 deep[v]= deep[u]+ 1; //深度也要 +1;
66                 q.push(v); //加入队列;
67             }
68         }
69     }
70 }
71 void into()
72 {
73     memset(Head, -1, sizeof(Head));
74     tnt= -1;
75 }
76
77 int main()
78 {
79     int n, m;
80     int c, d, e;
81     int a, b ,w;
82     while (~ scanf("%d %d", &n, &m))
83     {
84         scanf("%d %d %d", &c, &d, &e);
85         into();
86         for (int i= 0;i< m;i ++)
87         {
88             scanf("%d %d %d", &a, &b, &w);
89             Add_ENode(a, b, w);
90         }
91         Dijkstra(1, d, e);
92         if (Dis_Level[n]== inf) printf("-1\n");
93         else printf("%lld\n", (long long)Dis_Level[n]* c);
94     }
95     return 0;
96 }

View Code

4.Marriage Match IV (HDU 3416)

Starvae在A市,女孩在B市。每次starvae都可以到达B市并与他喜欢的女孩一起xoxo。但是他面前有两个问题,一是starvae必须在最短的时间内到达B,所以说他必须选择最短的路径;二是每条道路只能走一次,但每座城市他可以经过多次。那么,请你告诉他:从A-->B的(完全不同的)最短路径一共有几条?

Ps:最短路径+最大流。先用Dijkstra求出A到B的最短路径并处理dis[]数组,然后依照条件(dis[v]== dis[u]+ edegs[k].w)找出所有在最短路径上的边,并建一个图2。随后就是Dinic跑最大流出结果,代码如下。

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<queue>
  6 using namespace std;
  7 const int maxv= 1010;
  8 const int maxe= 400010;
  9 const int inf= 0x3f3f3f3f;
 10
 11 struct ENode
 12 {
 13     int to;
 14     int w;
 15     int Next;
 16 };
 17 ENode edegs[maxe];
 18 int Head[maxv], tnt;
 19 void init()
 20 {
 21     memset(Head, -1, sizeof(Head));
 22     tnt= -1;
 23 }
 24 void Add_ENode(int a, int b, int w)
 25 {
 26     ++ tnt;
 27     edegs[tnt].to= b;
 28     edegs[tnt].w= w;
 29     edegs[tnt].Next= Head[a];
 30     Head[a]= tnt;
 31 }
 32
 33 int dis[maxv];
 34 struct cmpx
 35 {
 36     bool operator() (int &a, int &b) const
 37     {
 38         return dis[a]- dis[b]> 0;
 39     }
 40 };
 41 void Dijkstra(int x)
 42 {
 43     priority_queue<int, vector<int>, cmpx> q;
 44     memset(dis, inf, sizeof(dis));
 45     dis[x]= 0;
 46     q.push(x);
 47
 48     while (! q.empty())
 49     {
 50         int u= q.top();
 51         q.pop();
 52
 53         for (int k= Head[u]; k!= -1; k= edegs[k].Next)
 54         {
 55             int v=  edegs[k].to;
 56             if (dis[v]> dis[u]+ edegs[k].w )
 57             {
 58                 dis[v]= dis[u]+ edegs[k].w;
 59                 q.push(v);
 60             }
 61         }
 62     }
 63 }
 64
 65 /*建新图,跑最大流*/
 66 ENode edegs1[maxe];
 67 int Head1[maxv], tnt1;
 68 void init1()
 69 {
 70     memset(Head1, -1, sizeof(Head1));
 71     tnt1= -1;
 72 }
 73 void Add_ENode1(int a, int b, int w)
 74 {
 75     ++ tnt1;
 76     edegs1[tnt1].to= b;
 77     edegs1[tnt1].w= w;
 78     edegs1[tnt1].Next= Head1[a];
 79     Head1[a]= tnt1;
 80     ++ tnt1;
 81     edegs1[tnt1].to= a;
 82     edegs1[tnt1].w= 0;
 83     edegs1[tnt1].Next= Head1[b];
 84     Head1[b]= tnt1;
 85 }
 86 void Dijk2(int n)
 87 {
 88     init1();
 89     for (int u= 1; u<= n; u ++)
 90     {
 91         for (int k= Head[u]; k!= -1; k= edegs[k].Next)
 92         {
 93             int v=  edegs[k].to;
 94             if (dis[v]== dis[u]+ edegs[k].w )
 95             {
 96                 Add_ENode1(u, v, 1);
 97             }
 98         }
 99     }
100 }
101 int level[maxv];
102 bool bfs_level (int s, int t)
103 {
104     memset(level, -1, sizeof(level)); //所有点的等级初始化为-1;
105     level[s]= 1; //源点的等级为1;
106     int que[maxv];  //队列que:按序保存已搜索到的点;
107     int iq= 0;
108     que[iq ++]= s; //先将源点s 加入队列;
109     for (int i= 0; i< iq; i ++)
110     {
111         int u= que[i];  //取出队首元素;
112         if (u== t)
113         {
114             /*找到汇点t,返回*/
115             return true;
116         }
117         for (int k= Head1[u]; k!= -1; k= edegs1[k].Next)
118         {
119             /*遍历,查找到之前未找到的、可抵达的点便加入队列*/
120             int v= edegs1[k].to;
121             if (-1== level[v]&& edegs1[k].w)
122             {
123                 level[v]= level[u]+ 1; //深度 +1;
124                 que[iq ++]= v;
125             }
126         }
127     }
128     return false;
129 }
130 int dfs(int now, int c_max, int t)
131 {
132     /**DFS 实现多路增广*/
133     /*now:起点;c_max:从源点s到节点now的最大流量;t:汇点、dfs结束的终点*/
134     if (now== t) return c_max; //当now== t时,c_max便是要求的最大流;
135     int ret= 0, f;
136     for (int k= Head1[now]; k!= -1; k= edegs1[k].Next)
137     {
138         if (edegs1[k].w&& level[edegs1[k] .to]== level[now]+ 1)
139         {
140             /**/
141             f= dfs(edegs1[k].to, min(c_max- ret, edegs1[k].w), t);
142             edegs1[k].w-= f;
143             edegs1[k^1].w+= f;
144             ret+= f;
145             if(ret== c_max) return ret;
146         }
147     }
148     return ret;
149 }
150 int dinic(int s, int t)
151 {
152     int ans= 0;
153     while(bfs_level(s, t))
154     {
155         ans+= dfs(s, inf, t);
156     }
157     return ans;
158 }
159
160 int main()
161 {
162     int t;
163     int n, m;
164     scanf("%d", &t);
165     while (t --)
166     {
167         scanf("%d %d", &n, &m);
168         init();
169         int a, b, w;
170         for (int i= 0; i< m; i ++)
171         {
172             scanf("%d %d %d", &a, &b, &w);
173             Add_ENode(a, b, w);
174         }
175         int start, endd;
176         scanf("%d %d", &start, &endd);
177         Dijkstra(start);
178         Dijk2(n);
179         int ans= dinic(start, endd);
180         printf("%d\n", ans);
181     }
182     return 0;
183 }

View Code

end;

转载于:https://www.cnblogs.com/Amaris-diana/p/10778340.html

专题训练——[kuangbin带你飞]最短路练习相关推荐

  1. 解题报告:【kuangbin带你飞】专题四 最短路练习题

    目录 A. POJ - 2387 TiltheCowsComeHomeTil\ the\ Cows\ Come\ HomeTil the Cows Come Home--------(最短路模板题)[ ...

  2. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

  3. kuangbin带你飞 专题1-23 题单

    kuangbin大神,对于打过ACM比赛的ACMer,无人不知无人不晓. 在此,附上vjudge平台上一位大神整理的[kuangbin带你飞]专题目录链接. [kuangbin带你飞专题目录1-23] ...

  4. “kuangbin带你飞”专题计划——专题十四:数论基础

    写在前面 1.目前还没啥写的.开始时间:2021-05-13(其实博客上看得到该博客创建时间的) 2.上一个专题刷的是网络流(博客总结),属于第一次接触.本来想的是一周特别高效,然后一周略划水,结果是 ...

  5. (2021-07-14~)“kuangbin带你飞”专题计划——专题十三:基础计算几何

    目录 前言 参考博客 自己总结的东西: 难度判断? 题目 1.[TOYS POJ - 2318 ](解决) 2.[Toy Storage POJ - 2398 ](解决) 3.[Segments PO ...

  6. 【kuangbin带你飞】专题六 最小生成树

    [kuangbin带你飞]专题六 最小生成树 A.POJ - 1251 Jungle Roads (最小生成树模板) The Head Elder of the tropical island of ...

  7. [kuangbin带你飞]专题十二 基础DP1 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 简单dp,最近在做,持续更新. 文章目录 总结: 1.Max Sum Plus Plus 2.Ignatius and the Princess IV ...

  8. [kuangbin带你飞]专题五 并查集 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 本人算是初学者中的初学者,欢迎交流~ 并查集的接触过的不多,大概只有普通并查集,带权并查集,种族并查集,传说中的可持续化并查集只是听说过还没有接触,不过 ...

  9. 线段树开新坑:kuangbin带你飞

    写在最前面的废话 这里I以前的题是暑假刚刚开始的时候在家写的,然后多校一波就荒废了 9月开头回家一波,重新填坑,= =,kuangbin带你飞的pdf,这才一半题,后面还有一波,蓝瘦,慢慢写吧,不写题 ...

  10. [kuangbin带你飞]专题四 做题顺序与题解 【最短路练习】

    随便说点: 博主正在刷kuangbin专题的题目,初学者,没接触过什么算法,刷题的初衷是备战蓝桥杯,后来发现了算法资料大多是针对acm的,挑选kuangbin专题入门也是如此,毕竟这样分类看起来能达到 ...

最新文章

  1. java鼠标监听事件_JAVA 鼠标事件监听ACTIONLISTENER
  2. docusign文档打不开_怎样查看 docusign pdf 电子签名
  3. MySQL中Myisam、InnoDB碎片优化
  4. mysqldump 的常用参数。
  5. java能不能修改文件大小信息_java上机考试3
  6. [高精度乘法]BZOJ 1754 [Usaco2005 qua]Bull Math
  7. Linux下,C++编程论坛题目抽取
  8. react入门(1)之阮一峰react教程
  9. mysql 创建表格time类型_记一次关于 Mysql 中 text 类型和索引问题引起的慢查询的定位及优化...
  10. 【报告分享】万达文旅项目新媒体营销操作手册.pdf(附下载链接)
  11. 数据流图技术相关基础知识
  12. 异步任务结果显示策略
  13. 我的实例我做主--ECS运维必读
  14. bug—jupyter notebook 连接不上kernel内核问题
  15. 自定义Flash背景的相关设置方法以及其与目录下的文件的对应关系
  16. ubuntu mysql 5.0_ubuntu server 8.04 下的mysql5.0的集群实验
  17. win8优化(win8优化大师设置开始界面)
  18. springboot Vue java学生宿舍报修管理系统源码介绍
  19. vs2015软件系统开源_2015年最佳开源游戏
  20. 20行代码教你如何批量提取图片中文字

热门文章

  1. 歌声带着失意囚徒的梦想直入云霄
  2. Rearchitect Your Web Applications for Microsoft ASP.NET 2.0
  3. H3C PBR实验(策略路由)
  4. Deepin linux 15.9.1 Ubuntu 16.04 安装zsteg、gem
  5. 一个学习爱好者,应该怎么学习golang
  6. kill 与 killall和过滤后杀掉
  7. vue 报错 :属性undefined(页面成功渲染)
  8. cookie 操作
  9. 在libvirt中使用SanLock
  10. 《Total Commander:万能文件管理器》——第4.5节.其他补充