图论——最短路
最短路
lllllan.
盛意以江河,江河不及你
展开
-
Floyd最小环
今天在找最短路题目做的时候碰到了最小环,直接呆了,能想得到可以通过删除 i->j 的直接路径 w,然后通过 dijkstra 计算 i->j 最短路 dis[j],相加 w+dis[j] 就构成了环,但这样太麻烦了吧。 然后就去学习了Floyd的最小环,老实说我只看懂了一半,由于各方博客上的文字说明统统避开了我的疑惑点,好在是个简单模板,暂时先强行记忆了。 例题:hdu1599Problem Description杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条原创 2020-07-21 22:43:18 · 136 阅读 · 0 评论 -
SPFA算法
最短路径问题从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径。解决方法:Dijkstra算法 Floyd算法 Bellman-Ford算法 SPFA算法SPFA算法算法特点:用于解决单源最短路径问题,并且具有判断负圈的功能。(本来Bellman-Ford算法是用数组解决的,而我偷懒用了队列来方便我加边)SPFA利用队列对Bellman-Ford进行了优化,舍去了一些无效的操作,效率要高很多。算法思路:回顾一下Bellman-Ford的算法,仅针原创 2020-07-06 11:06:44 · 245 阅读 · 0 评论 -
Bellman-Ford算法
最短路径问题从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径。解决方法:Dijkstra算法 Floyd算法 Bellman-Ford算法Bellman-Ford算法算法特点:用于解决单源最短路径问题,并且具有判断负圈的功能。该算法只对相邻节点进行计算,可以避免Floyd那种大撒网式的无效计算,相对提高了效率(因为对比Dijkstra仍然略显笨重)。算法思路:初始时,设所有节点到原点的距离为inf即无限大。第一轮:从原点节点开始,判断它的相邻原创 2020-07-06 00:10:05 · 598 阅读 · 0 评论 -
Floyd算法
最短路径问题从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径。解决方法:Dijkstra算法 Floyd算法 Bellman-Ford算法Floyd算法算法特点:可用于求出每两点之间的最短路。优点是代码简单,能够求任意两点的最短路;缺点是暴力带来的时间复杂度较大,不适合用在点较多的图中。算法思路:定义一个二维数组dis[n][n]用于存放i点到j点的最短距离,在调用它之前只需要做简答的初始化:dis[i][i]=0,其他的dis值为正无穷inf。原创 2020-07-05 05:27:09 · 271 阅读 · 0 评论 -
Dijkstra算法图解
最短路径问题从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径。Djikstra算法算法特点:Dijkstra算法适用于计算正权图(边权为正)上的单源最短路,即从单个源点出发,到所有节点的最短路。该算法同时适用于有向图和无向图。算法思路:从已确定最短路径的节点Vi出发,找到其中权值最小的边,如果原点到Vi的权值和加Vi到Vj的权值小于已知原点到Vj的权值和,则将原点到Vi的权值和加Vi到Vj的权值作为原点到Vj的最小权和。(讲的有点不是特别清楚,看图分析)原创 2020-07-04 12:40:35 · 2778 阅读 · 0 评论 -
POJ3268 Silver Cow Party【正反图 + Dijkstra】
Silver Cow Party题意: 在一个有向图中,求所有点到达X点并返回出发点的最小距离其中的最大值。题解: 求一遍某点到到X点需要跑一次Dijkstra,再求X点到某点又需要一次Dijkstra,而且Dijkstra只能拿来求单源的最短路。所以在求第一段最短路的时候,可以建一个反图,求出X到所有点的最小距离即所有点到X的最小距离。#include<iostream>#include<algorithm>#include<queue>#i...原创 2020-11-16 12:02:57 · 102 阅读 · 0 评论 -
POJ2253 Frogger【Dijkstra】
Frogger题意: 给定一个无向图,求到达2号点的路径中(不要求最短),边权最大值最小。#include<algorithm>#include<iostream>#include<cmath>#include<queue>using namespace std;#define _for(i, a, b) for(int i = (a); i <= (b); ++i)typedef long long ll;const...原创 2020-11-16 11:57:17 · 98 阅读 · 0 评论 -
POJ1797 Heavy Transportation【Dijkstra】
Heavy Transportation题意: 在一个无向图中,求一条1号点到N号点的路径,要求使得路径中的边权最小值最大。题解: 只针对单条边的边权,只要在Dijkstra的基础上,将按距离从小到大排序改成按单条边权从大到小排序,求到达n点路上的最小值即可。#include<iostream>#include<algorithm>#include<queue>#include<vector>using namespace std...原创 2020-11-16 11:52:11 · 98 阅读 · 0 评论 -
CodeForces - 450D Jzzhu and Cities【Dijkstra + 删除特殊边】⭐
Jzzhu and Cities题意: 给定一个无向图,图中有m条普通的公路和k条从1点出发的铁路。问在不影响从1点到所有点的最短路情况下,最多可以删除多少条铁路。题解: 又犯了大忌,千万不要在Dij中添加太多的所谓限制条件,只会越搞越乱。办法就是记录下到某个点的最短路的条数。然后在保证条数大于0的情况下去删除铁路即可。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int i...原创 2020-11-02 20:34:07 · 145 阅读 · 0 评论 -
HDU2680 Choose the best route【Dijkstra】
Choose the best route题意: 给定一个n个点、m条边的有向图,你有k个起点可以选择,求到终点s的最短路。题解: 需要注意的只有:多个起点,只要建立一个超级起点,连通这些起点即可。有向图。一开始没看清题意直接按照无向图写wa了一发。两点之间可能多边。用链式前向星存图直接无视这种坑点。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int inf = ...原创 2020-10-31 21:37:49 · 272 阅读 · 0 评论 -
POJ3169 Layout【差分约束系统入门——SPFA】
Layout题意: 有些奶牛之间关系好,距离不能超过一定距离,有些奶牛关系不好,距离不能小于一定距离。问一号奶牛和n号奶牛的可能的最大距离,如果不存在满足要求的方案,输出-1;如果1号奶牛和N号奶牛间的距离可以任意大,输出-2题解: 直接看这篇博客学习差分约束系统,回来加亿点细节套最短路的SPFA模板就能做。注意: 我们并不知道根据所给的约束条件,是否能够建立起一个连通的图,所以可以将所有的点和饥饿一个超级源点连接一条权值为0的边,使其成为一个连通图。#include<algo...原创 2020-10-17 18:35:33 · 125 阅读 · 0 评论 -
POJ2387 Til the Cows Come Home【Dijkstra】
Til the Cows Come Home最短路落题,如果是邻接表存图,则要小心重边。换作是链式前向星存图就没事了。#include<algorithm>#include<iostream>#include<cstring>#include<iomanip>#include<cstdio>#include<string>#include<vector>#include<cmath&g...原创 2020-10-17 18:19:50 · 129 阅读 · 0 评论 -
9/16Contest H. Hsueh- and keyboard——Dijkstra
点这里Hsueh- has a keyboard.There is a string which has x characters in the textarea.At present, Hsueh- wants to see a string of length exactly n in the textarea.You can use the following operations to meet Hsueh-'s requirements.Strike the keyboa...原创 2020-09-20 09:59:34 · 123 阅读 · 0 评论 -
HDU1526 A Plug for UNIX——二分匹配+传递闭包
点这里题意: 房间里有a个插座和b个电器设备,以及c个适配器,相同接口的设备可以直接连接插座,不同接口的也可以使用适配器来连接。问最少有多少个设备没有插座可以用。题解: 都这么问了,显然就是二分图最大匹配的问题了,可以选择用最大流的模板去做,也可以用比较简洁的匈牙利算法。问题在于适配器的问题怎么处理——Floyd传递闭包。下面代码为二分匹配的匈牙利算法。过程中犯的错:cnt的初始化: 必须从1开始。#include<iostream>#include<al...原创 2020-09-10 14:53:50 · 88 阅读 · 0 评论 -
POJ 2135Farm Tour——最小费用最大流模板
点这里题意: 给定一个无向图,有n个地点、m条边。一个人从1号点走到n号点,再从n号点走回1号点,每条路只能走一次。求一个来回的总长度最短的路线。题解: 既然是无向图,那么题目就可以转换成从1号点到n号点至少有两条不同的路径,找其中两条,是他们的总长度最短。 这一题实际上是最小费用最大流的裸题,建模如下: 把每条边的流量设为1,表示每条边只能用1次,把边的长度看成每条边的费用。在图中添加一个超级源点S和一个超级汇点T,S到1的有一个长度为0、容量为2的边,n到T有一个长度为0、容量...原创 2020-09-08 15:34:55 · 159 阅读 · 0 评论 -
POJ3615 Cow Hurdles——Floyd(水)
点这里题意: 给定一个带权有向图,n个点m条边以及t次查询。规则如下:某个点u到某个点v的花费为,路径上的最大权值。t次查询要求输出某点u到某点v的最小花费,如果无法到达则输出-1。题解: 显然是一个多源的最短路问题,而且最多有三百个点,是可以用Floyd算法的,而且用Floyd也比较方便。其次在花费的计算上有所不同,某条路径的花费为这些路上的最大权值。所以我们的Floyd有需要改变的地方。过程中犯的错:Floyd变形: 因为要求的是最小的最大花费(好像听上去有点矛盾,但是你读懂题...原创 2020-09-06 08:39:45 · 138 阅读 · 0 评论 -
POJ3159 Candies——Dijkstra板子题
点这里题意: 就是求1到n的最短距离。直接套模板就行。#include <iostream>#include <algorithm>#include <queue>using namespace std;const int inf = 0x3f3f3f3f;const int maxm = 1e6;const int maxn = 3e4 + 10;int n, m, cnt;int vis[maxn]; int head[maxm]...原创 2020-09-05 16:39:05 · 139 阅读 · 0 评论 -
POJ1511 Invitation Cards——Dijkstra+正图、反图
点这里题意: 给定一个带权有向图G,求原图下的1点到所有点的最短路之和sum1,再求将所有边反过来之后1点到所有点的最短路之和sum2,输出sum1 + sum2.题解: 记录好每条边的起点、终点和权值,跑一边Dijkstra之后将所有边反过来再求一边就可以了。几乎就是套模板了,可以参考Dijkstra算法图解。过程中犯的错:反图: 一开始没弄清楚题意,以为先求一遍1点到所有点的最短路之和,再求n点到所有点的最短路之和。其实是要将边反过来。long long: int是不够用的。...原创 2020-09-05 16:00:05 · 171 阅读 · 0 评论 -
POJ3259 Wormholes——判负圈(SPFA)
点这里题意: 给定一个带权混合图,有n个点,m条权值为正的双向边,w条权值为负的单项边。判断是否存在负圈。题解: 唯一要注意的就是既有无向边,也有单向边;以及单向边的权值是负的(输入的是正数,但代表的是负数)。剩下的几乎不用改模板,可直接参考SPFA算法。#include<iostream>#include<algorithm>#include<queue>using namespace std;const int N = 505;const...原创 2020-09-05 15:08:35 · 107 阅读 · 0 评论 -
HDU2433 Travel——枚举/删边+Dijkstra
点这里题意: 给定一个无向图,有n个点和m条边,每条边的权值均为1。要求每次只删除第i条边(分别删除m条边中的其中一条,求答案),求所有点之间的最短距离和,如果存在不连通的点则输出INF。题解: 最多有三千条边,显然不可能分别删除,然后又分别去求所有点的最短距离,最后求和;也就是说这么做的话,我们可能需要运行3000*3000次Dijkstra。那么我们就要考虑什么样子的情况下,可以省去重复或者无用的计算。重边: 看样例就知道是有可能存在重边的,那么在存在重边的情况下,我们删除重边的其...原创 2020-09-03 15:29:01 · 175 阅读 · 0 评论 -
HDU1704 Rank——传递闭包(Floyd)
点这里题意: n个人和m场一对一的比赛,问比赛完之后,还有多少排名关系不能确定。题解: 谈谈传递闭包以及自己杂想、传递闭包 知道传递闭包的话就不用多解释了。过程中犯的错:TLE: Floyd虽然好用,但是输在时间复杂度上,因此在第二个for循环的下面加了一个if语句,可以减少一些时间复杂度。#include<bits/stdc++.h>using namespace std;const int N = 510;int T, n, m, a, b;...原创 2020-09-03 10:10:11 · 136 阅读 · 0 评论 -
HDU3631 Shortest Path——Floyd巧妙应用(⭐)
点这里题意: 给定一个加权有向图,有n个点、m条边以及q条操作。q条操作中,有两种类型0 u表示将u点做上标记,1 u v表示计算u点和v的最短距离, 要求是最短路径上包括u、v的所有点都做上标记。 针对不同情况:ERROR! At point x: 重复给x做标记则输出该语句。ERROR! At path x to y: 要求最短路的两端点并未全做上标记则输出该语句。No such path: 两端点都已做上标记,但是这两点间没有路。最短距离: 两点都已做上标记,并且两点间存在最...原创 2020-09-03 09:13:19 · 131 阅读 · 0 评论 -
HDU1217 && POJ2240 Arbitrage——字符串+Floyd
点这里题意: n种货币和m种兑换方式,如果存在某种兑换路径使得,货币x兑换一圈回来以后获得更多的货币x,则输出Yes,否则输出No。题解: 因为货币是以字符串形式出现的,同样是把字符串转变成数字之后再用Floyd的模板,函数里稍稍改动一下就可以了。strcmp处理这是我翻到的半年前做的,有些青涩啊,当时可能还不知道map,也不会想到有没有什么方便的工具可以使用。就老老实实地挨个去查找,然后赋予数值。#include<bits/stdc++.h>using namespace st原创 2020-08-19 11:27:44 · 250 阅读 · 0 评论 -
HDU2112 HDU Today——字符串地名+Floyd
点这里题意: 告诉你有n路公交车,先给出起点和终点的地名,注意是字符串类型;然后依次给出n路公交车的起点、终点和所需时间。如果能从起点到目的地,则输出最短距离,不能到达则输出-1。题解: 地名从一般题目的数字变成了字符串而已,那我们就把字符串转换回数字,我用了map,如果这个地名先前没有出现过,我就赋予他一个新的int值;如果出现过,那就使用先前赋予的值。转换成数字之后,用最简单的Floyd的模板就能做。做题过程中做错的点:初始化,又无脑地memset(dis, inf, sizeof dis原创 2020-08-19 10:53:02 · 133 阅读 · 0 评论 -
POJ 1062 昂贵的聘礼——Dijkstra/DFS
传送门题意: (反正题目就是中文的,理解起来应该不会有太大问题)题解: 一看就知道是最短路问题,但因为有个等级限制需要做一些小小的处理,最简单的是一开始就框定一个等级范围,然后在范围内的才进行交换,然后更新最小值。当然这样需要遍历所有范围,进行多次最短路求解(在这个问题里是不会超时的。也因为这个交易是单向的,所以用DFS搜索也挺方便的。Dijkstra解决#include <iostream>#include <algorithm>#include <vector&原创 2020-08-02 16:10:20 · 127 阅读 · 0 评论 -
HDU 1317 XYZZY——spfa、有环
传送门题意: 多组数据,首行数字表示有n个房间,接下来n行第一个数表示第i个房间的能量值,然后数值k表示这个房间能通往k个房间。每个房间从1到n编号。要求从房间1走到房间n,途中必须保证能力值大于0。可以多次到达同一个房间多次吸收能量,但是房间间的路是单向边。题解: 两个关键,1途中的能力值必须大于0,2可以反复到达一个有收益的房间。第一点还是容易保证的;关键在于2,既要能构成一个环、其能力值的收益还必须为正、并且这个环能通向终点。结构体存边#include<iostream>#inc原创 2020-08-02 15:16:24 · 137 阅读 · 0 评论 -
HDU 1595 find the longest of the shortest(删边+多次dijkstra)
传送门Problem DescriptionMarica is very angry with Mirko because he found a new girlfriend and she seeks revenge.Since she doesn’t live in the same city, she started preparing for the long journey.We know for every road how many minutes it takes to come fro原创 2020-07-21 23:13:15 · 161 阅读 · 0 评论 -
hdu 1596 Floyd水题
传送门Problem DescriptionXX星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在 0 和 1 间的实数(包括0,1),一条从u 到 v 的通道P 的安全度为Safe§ = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的边 ,现在8600 想出去旅游,面对这这么多的路,他想找一条最安全的路。但是8600 的数学不好,想请你帮忙 _Input输入包括多个测试实例,每个实例包括:第一行:n。n表示城市的个原创 2020-07-21 22:50:11 · 248 阅读 · 0 评论 -
HDU2680(两点间多边,避坑
传送门注意要点:两点之间可能存在多边,我的模板中除了floyd都是处理不了多边的,但是floyd在这题显然是不够看的,直接超时。处理的办法就是舍弃存边的结构体edge,像floyd一样定义一个d[num][num]来存放两点间的坐车时间,输入时选取两点之间的最小时间即可。对于只有个别站能乘坐的问题,只要设该站到原点的时间为0,最后求目的地到原点的时间即可。#include<iostream>#include<algorithm>#include<queue>原创 2020-07-08 19:32:01 · 151 阅读 · 0 评论 -
HDU2066——Dijkstra、Bellman-Ford
传送门我好菜,题目看着很简单,实际确实很简单,但是还是wa了很多遍。先是白痴地试了一下Floyd,不出意外地超时了。然后直接上手Dijkstra,结果wa了,我,,,确实菜。然后就写了一边Bellman-Ford,ac了,回头的就发现了Dijkstra的问题出在对dis[i]的初始化。Floyd算法,超时。#include<iostream>#include<algorithm>using namespace std;const int inf = 0x3f原创 2020-07-06 23:57:56 · 174 阅读 · 0 评论 -
最短路练习一(水题)
HDU1874(Floyd解决)#include<iostream>#include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 205;int n, m, dis[maxn][maxn];void Floyd(){ for(int k=0; k<n; k++) for(int i=0; i<n; i++)原创 2020-07-06 22:57:51 · 208 阅读 · 0 评论