专题训练——[kuangbin带你飞]最短路练习
最短路练习
0. Til the Cows Come Home POJ - 2387
完美的模板题
- //#include<Windows.h>
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- using namespace std;
- const int MAX_V = ;
- const int MAX_E = ;
- const int inf = 0x3f3f3f3f;
- struct ENode
- {
- int to;
- int Next;
- int w;
- };
- ENode Edegs[MAX_E];
- int Head[MAX_V];
- int Dis[MAX_V];
- int tnt;
- void Add_ENode(int u, int v, int w)
- {
- ++tnt;
- Edegs[tnt].to = v;
- Edegs[tnt].w = w;
- Edegs[tnt].Next = Head[u];
- Head[u] = tnt;
- ++tnt;
- Edegs[tnt].to = u;
- Edegs[tnt].w = w;
- Edegs[tnt].Next = Head[v];
- Head[v] = tnt;
- }
- struct cmpx
- {
- bool operator () (int &a, int &b) const
- {
- return Dis[a] - Dis[b] > ;
- }
- };
- void Dijkstra(int x)
- {
- priority_queue<int, vector<int>, cmpx> q;
- memset(Dis, inf, sizeof(Dis));
- Dis[x] = ;
- q.push(x);
- while (!q.empty())
- {
- int u = q.top();
- q.pop();
- for (int k = Head[u]; k != -; k= Edegs[k].Next)
- {
- int v = Edegs[k].to;
- if (Dis[v] > Dis[u] + Edegs[k].w)
- {
- Dis[v] = Dis[u] + Edegs[k].w;
- q.push(v);
- }
- }
- }
- }
- int main()
- {
- int t, n;
- cin >> t >> n;
- tnt = -;
- int a, b, w;
- memset(Head, -, sizeof(Head));
- for (int i = ; i < t; i++)
- {
- cin >> a >> b >> w;
- Add_ENode(a, b, w);
- }
- Dijkstra();
- cout << Dis[n] << endl;
- // system("pause");
- return ;
- }
1. Frogger POJ - 2253
青蛙和石头。在池塘里有2只青蛙和n块石头,石头之间有一定距离,现在一只(腿短的)青蛙想要去找另一只青蛙yuehui;给出n块石头的坐标,1号为男主青蛙所在的石头,二号为目标石头。他想尽可能的省力,每次都跳的尽量短。问它在所有可行路径中单次跳跃需要的最长距离的最小值是多少?
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- #include<cmath>
- using namespace std;
- const int MAX_V= ;
- const double inf= 99999999999999999.0;
- typedef pair<double, double> _pair;
- _pair rock[MAX_V];
- double get_dis(_pair a, _pair b)
- {
- return sqrt(((a.first- b.first)* (a.first- b.first) )+ ((a.second- b.second)* (a.second- b.second) ) );
- }
- double Dis[MAX_V];
- struct cmpx
- {
- bool operator() (int &a, int &b) const
- {
- return Dis[a]- Dis[b]> ;
- }
- };
- int Front[MAX_V];
- void Dijkstra(int n)
- {
- priority_queue<int, vector<int>, cmpx> q;
- fill(Dis, Dis+ n+ , inf);
- //for(int i= 1; i<= n; i ++) printf("%f\n", Dis[2]);
- Dis[]= ;
- Front[]= -;
- q.push();
- while (! q.empty() )
- {
- int u= q.top();
- q.pop();
- for (int i= ; i<= n; i ++)
- {
- if (i== u) continue;
- double detmp= get_dis(rock[u], rock[i]);
- //printf("%f---%f---%f\n", Dis[u], detmp, Dis[i]);
- if (Dis[i]> Dis[u]&& Dis[i]> detmp)
- {
- Dis[i]= max(Dis[u], detmp);
- Front[i]= u;
- q.push(i);
- }
- //printf("%f\n", Dis[i]);
- }
- }
- }
- int main()
- {
- int n;
- int t= ;
- while (cin >> n)
- {
- ++ t;
- if (n== ) break;
- for (int i= ; i<= n; i ++)
- {
- cin >> rock[i].first >> rock[i].second;
- }
- //for(int i= 2; i<= n; i ++) printf("%f\n", get_dis(rock[1], rock[i]));
- Dijkstra(n);
- printf("Scenario #%d\n",t);
- printf("Frog Distance = %.3f\n\n", Dis[]);
- double ans= -1.0;
- /*for (int c= n; c!= 1; c= Front[c])
- {
- double cnp= get_dis(rock[c], rock[Front[c]]);
- ans= max(ans, cnp);
- }
- printf("Frog Distance = %.3f\n\n", ans);*/
- }
- return ;
- }
2. Heavy Transportation POJ - 1797
城市中有N个路口,M个街道,每条街道都有最大承重限制;现在我们想要驾车从1号路口到N号路口,那么运输车所允许的最大重量是多少?
(不知道为什么老是PE,懒得改了)
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- using namespace std;
- const int maxv= ;
- const int maxe= ;
- const int inf= 0x3f3f3f3f;
- struct ENode
- {
- int to;
- int w;
- int Next;
- };
- ENode edegs[maxe];
- int Head[maxv], tnt;
- void init()
- {
- memset(Head, -, sizeof(Head));
- tnt= -;
- }
- void Add_ENode(int a, int b, int w)
- {
- ++ tnt;
- edegs[tnt].to= b;
- edegs[tnt].w= w;
- edegs[tnt].Next= Head[a];
- Head[a]= tnt;
- ++ tnt;
- edegs[tnt].to= a;
- edegs[tnt].w= w;
- edegs[tnt].Next= Head[b];
- Head[b]= tnt;
- }
- int dis[maxv];
- struct cmpx
- {
- bool operator() (int &a, int &b) const
- {
- return dis[a]- dis[b]< ;
- }
- };
- void Dijkstra(int x)
- {
- priority_queue<int, vector<int>, cmpx> q;
- memset(dis, , sizeof(dis));
- dis[x]= inf;
- q.push(x);
- while (! q.empty())
- {
- int u= q.top();
- q.pop();
- for (int k= Head[u]; k!= -; k= edegs[k].Next)
- {
- int v= edegs[k].to;
- if (dis[v]< min(dis[u], edegs[k].w))
- {
- dis[v]= min(dis[u], edegs[k].w);
- q.push(v);
- }
- }
- }
- }
- int main()
- {
- int t, Case= ;
- int n, m;
- scanf("%d", &t);
- while (t --)
- {
- ++ Case;
- scanf("%d %d", &n, &m);
- init();
- int a, b, w;
- for (int i= ; i< m; i ++)
- {
- scanf("%d %d %d", &a, &b, &w);
- Add_ENode(a, b, w);
- }
- Dijkstra();
- printf("Scenario #%d:\n%d\n", Case, dis[n]);
- }
- return ;
- }
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了。
- #include<algorithm>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- using namespace std;
- const int MAX_V= ;
- const int MAX_E= ;
- const int inf= 0x3f3f3f3f;
- struct ENode
- {
- int to;
- int w;
- int Next;
- };
- ENode edegs[MAX_E];
- int Head[MAX_V], tnt;
- void Add_ENode(int a, int b, int w)
- {
- edegs[++ tnt].to= b;
- edegs[tnt].w= w;
- edegs[tnt].Next= Head[a];
- Head[a]= tnt;
- edegs[++ tnt].to= a;
- edegs[tnt].w= w;
- edegs[tnt].Next= Head[b];
- Head[b]= tnt;
- }
- int Dis_Level[MAX_V]; //到每个点,所需要的飞船最小等级;
- int deep[MAX_V]; //每个点bfs 的深度;
- struct cmpx
- {
- bool operator() (int &a, int &b) const
- {
- return Dis_Level[a]- Dis_Level[b]> ;
- }
- };
- void Dijkstra(int x, int _dis, int _cost)
- {
- /*x为起点, _dis是每次升级提升的传送距离, _cost是升级提升的传送次数;*/
- memset(Dis_Level, inf, sizeof(Dis_Level));
- memset(deep, inf, sizeof(deep));
- priority_queue<int, vector<int>, cmpx> q;
- Dis_Level[x]= ; //起点的飞行器等级为0;
- deep[x]= ; //起点深度为0;
- q.push(x);
- while (! q.empty())
- {
- int u= q.top();
- q.pop();
- for (int k= Head[u]; k!= -; k= edegs[k].Next)
- {
- int v= edegs[k].to;
- int lev_tmp= Dis_Level[u];
- while (lev_tmp* _dis< edegs[k].w|| lev_tmp* _cost< deep[u]+ )
- {
- /*若当前的飞行器等级不能穿越此隧道,或传送次数已用完,则升级飞行器一次;*/
- lev_tmp ++;
- }
- if (lev_tmp< Dis_Level[v])
- {
- /*如果此时的飞行器等级小与之前到达点v 的飞行器等级,则更新Dis_Level[v]*/
- Dis_Level[v]= lev_tmp;
- deep[v]= deep[u]+ ; //深度也要 +1;
- q.push(v); //加入队列;
- }
- }
- }
- }
- void into()
- {
- memset(Head, -, sizeof(Head));
- tnt= -;
- }
- int main()
- {
- int n, m;
- int c, d, e;
- int a, b ,w;
- while (~ scanf("%d %d", &n, &m))
- {
- scanf("%d %d %d", &c, &d, &e);
- into();
- for (int i= ;i< m;i ++)
- {
- scanf("%d %d %d", &a, &b, &w);
- Add_ENode(a, b, w);
- }
- Dijkstra(, d, e);
- if (Dis_Level[n]== inf) printf("-1\n");
- else printf("%lld\n", (long long)Dis_Level[n]* c);
- }
- return ;
- }
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跑最大流出结果,代码如下。
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- using namespace std;
- const int maxv= ;
- const int maxe= ;
- const int inf= 0x3f3f3f3f;
- struct ENode
- {
- int to;
- int w;
- int Next;
- };
- ENode edegs[maxe];
- int Head[maxv], tnt;
- void init()
- {
- memset(Head, -, sizeof(Head));
- tnt= -;
- }
- void Add_ENode(int a, int b, int w)
- {
- ++ tnt;
- edegs[tnt].to= b;
- edegs[tnt].w= w;
- edegs[tnt].Next= Head[a];
- Head[a]= tnt;
- }
- int dis[maxv];
- struct cmpx
- {
- bool operator() (int &a, int &b) const
- {
- return dis[a]- dis[b]> ;
- }
- };
- void Dijkstra(int x)
- {
- priority_queue<int, vector<int>, cmpx> q;
- memset(dis, inf, sizeof(dis));
- dis[x]= ;
- q.push(x);
- while (! q.empty())
- {
- int u= q.top();
- q.pop();
- for (int k= Head[u]; k!= -; k= edegs[k].Next)
- {
- int v= edegs[k].to;
- if (dis[v]> dis[u]+ edegs[k].w )
- {
- dis[v]= dis[u]+ edegs[k].w;
- q.push(v);
- }
- }
- }
- }
- /*建新图,跑最大流*/
- ENode edegs1[maxe];
- int Head1[maxv], tnt1;
- void init1()
- {
- memset(Head1, -, sizeof(Head1));
- tnt1= -;
- }
- void Add_ENode1(int a, int b, int w)
- {
- ++ tnt1;
- edegs1[tnt1].to= b;
- edegs1[tnt1].w= w;
- edegs1[tnt1].Next= Head1[a];
- Head1[a]= tnt1;
- ++ tnt1;
- edegs1[tnt1].to= a;
- edegs1[tnt1].w= ;
- edegs1[tnt1].Next= Head1[b];
- Head1[b]= tnt1;
- }
- void Dijk2(int n)
- {
- init1();
- for (int u= ; u<= n; u ++)
- {
- for (int k= Head[u]; k!= -; k= edegs[k].Next)
- {
- int v= edegs[k].to;
- if (dis[v]== dis[u]+ edegs[k].w )
- {
- Add_ENode1(u, v, );
- }
- }
- }
- }
- int level[maxv];
- bool bfs_level (int s, int t)
- {
- memset(level, -, sizeof(level)); //所有点的等级初始化为-1;
- level[s]= ; //源点的等级为1;
- int que[maxv]; //队列que:按序保存已搜索到的点;
- int iq= ;
- que[iq ++]= s; //先将源点s 加入队列;
- for (int i= ; i< iq; i ++)
- {
- int u= que[i]; //取出队首元素;
- if (u== t)
- {
- /*找到汇点t,返回*/
- return true;
- }
- for (int k= Head1[u]; k!= -; k= edegs1[k].Next)
- {
- /*遍历,查找到之前未找到的、可抵达的点便加入队列*/
- int v= edegs1[k].to;
- if (-== level[v]&& edegs1[k].w)
- {
- level[v]= level[u]+ ; //深度 +1;
- que[iq ++]= v;
- }
- }
- }
- return false;
- }
- int dfs(int now, int c_max, int t)
- {
- /**DFS 实现多路增广*/
- /*now:起点;c_max:从源点s到节点now的最大流量;t:汇点、dfs结束的终点*/
- if (now== t) return c_max; //当now== t时,c_max便是要求的最大流;
- int ret= , f;
- for (int k= Head1[now]; k!= -; k= edegs1[k].Next)
- {
- if (edegs1[k].w&& level[edegs1[k] .to]== level[now]+ )
- {
- /**/
- f= dfs(edegs1[k].to, min(c_max- ret, edegs1[k].w), t);
- edegs1[k].w-= f;
- edegs1[k^].w+= f;
- ret+= f;
- if(ret== c_max) return ret;
- }
- }
- return ret;
- }
- int dinic(int s, int t)
- {
- int ans= ;
- while(bfs_level(s, t))
- {
- ans+= dfs(s, inf, t);
- }
- return ans;
- }
- int main()
- {
- int t;
- int n, m;
- scanf("%d", &t);
- while (t --)
- {
- scanf("%d %d", &n, &m);
- init();
- int a, b, w;
- for (int i= ; i< m; i ++)
- {
- scanf("%d %d %d", &a, &b, &w);
- Add_ENode(a, b, w);
- }
- int start, endd;
- scanf("%d %d", &start, &endd);
- Dijkstra(start);
- Dijk2(n);
- int ans= dinic(start, endd);
- printf("%d\n", ans);
- }
- return ;
- }
end;
专题训练——[kuangbin带你飞]最短路练习的更多相关文章
- kuangbin带你飞 最短路 题解
求一个图最短路边的办法.好像下面的那个有问题.单向边和双向边一定是有区别的.这个比较容易.参照该文的最短路网络流题目和连通图题目一题求最短路关节边 另外上述2个题目的代码好像有问题. 在UVALIVE ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
- 「kuangbin带你飞」专题十四 数论基础
layout: post title: 「kuangbin带你飞」专题十四 数论基础 author: "luowentaoaa" catalog: true tags: mathj ...
- 「kuangbin带你飞」专题二十 斜率DP
layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathj ...
- 「kuangbin带你飞」专题二十二 区间DP
layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...
- 「kuangbin带你飞」专题十九 矩阵
layout: post title: 「kuangbin带你飞」专题十九 矩阵 author: "luowentaoaa" catalog: true tags: mathjax ...
- 「kuangbin带你飞」专题十八 后缀数组
layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kua ...
随机推荐
- mysql 状态查询
select COUNT(case when info.State = '0' then State end ) as daichuliCount, COUNT(case when info.St ...
- VirtualBox搭建1主2从虚拟机
环境要求 最近在使用VirtualBox搭建一个实验环境,由于公司规定了所有的机器都不能使用固定IP,都必须由DHCP自动获取. 为了不影响公司整理的网络环境,只能把实验用的网络环境限制在使用内部IP ...
- Python函数缓存
函数缓存 (Function caching) 函数缓存允许我们将一个函数对于给定参数的返回值缓存起来.当一个I/O密集的函数被频繁使用相同的参数调用的时候,函数缓存可以节约时间.在Python 3. ...
- [Usaco2005 Jan]Muddy Fields泥泞的牧场
Description 雨连续不断的击打了放牛的牧场,一个R行C列的格子(1<=R<=50,1<=C<=50).虽然这对草来说是件好事,但这却使得一些没有草遮盖的土地变得很泥泞 ...
- 洛谷 P2742 [USACO5.1]圈奶牛Fencing the Cows || 凸包模板
整篇都是仅做记录... 蓝书上的板子.水平序,单调栈.先求下凸包,再求上凸包.叉积的作用是判定向量的位置关系. 48行的作用是在求上凸包的时候不至于去删下凸包中的点.上凸包中第一个点被认为是t1. 另 ...
- 415 Add Strings 字符串相加
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和.注意: num1 和num2 的长度都小于 5100. num1 和num2 都只包含数字 0-9. num1 和 ...
- ES6知识点汇总
MDN镇楼: https://developer.mozilla.org/zh-CN/ 1.ES6新添加数据类型:symbol ----------- https://developer.moz ...
- redis的安装使用以及一些常用的命令
Redis是一个key-value存储系统.并提供多种语言的API,我们可使用它构建高性能,可扩展的Web应用程序.目前越来越多的网站用它来当做缓存,减轻服务器的压力. 本文安装用的到redis是绿色 ...
- AJPFX总结面向对象特征之一的继承知识
继 承(面向对象特征之一) 好处: 1:提高了代码的复用性. 2:让类与类之间产生了关系,提供了另一个特征多态的前提. 父类的由来:其实是由多个类不断向上抽取共性内容而来的. java中对于继承, ...
- CF792C Divide by Three
思路: dp. 实现: #include <iostream> #include <cstdio> #include <cstring> #include < ...