天天看点

最短路专题【完结】

第一题 hdu 1317 XYZZY

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1317">点击打开hdu 1317</a>

思路:

1 题目的图是一个有向图,并且可能存在环。第一个点的能量值为100,边的权值利用能量大小,例如2点为-60,如果1-&gt;2那么value[1][2] = -60

2 题目明确指出如果是要win的话,那么必须是经过的每条边都要大于0.那么我们只要把那些经过松弛操作后的点大于0的入队即可,小于等于0的点肯定不会出现在最终的路径上。

3 如果存在正环的话,那么就有能量值无限大,那么这个时候只要判断这个点能否到达n

4 判断是否是有环还是五环,用一个s标记,s初始化为0,有环的时候另s = i,然后return。

5 判断当前点s能否到n直接利用dfs即可。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/7734776">点击查看代码</a>

第二题 uva 567 Risk

<a target="_blank" href="http://uva.onlinejudge.org/index.php?option=com_onlinejudge&amp;Itemid=8&amp;page=show_problem&amp;category=24&amp;problem=508&amp;mosmsg=Submission+received+with+ID+10622709">点击打开uva 567</a>

思路:最短路的模板题

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/7996412">点击查看代码</a>

第三题 hdu 1874 畅通工程续

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1874">点击打开hdu 1874</a>

思路:最短路模板题

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/7997820">点击查看代码</a>

第四题 uva 558 Wormholes

<a target="_blank" href="http://uva.onlinejudge.org/index.php?option=com_onlinejudge&amp;Itemid=8&amp;page=show_problem&amp;category=24&amp;problem=499&amp;mosmsg=Submission+received+with+ID+10628131">点击打开uva 558</a>

1 利用Bellman_Ford来判断是否存在回环

2 在利用Bellman_Fordde 时候如果做了n-1次的松弛步以后还能更新dis数组,那么说明原来的图中存在环,那么最短路就是不存在的。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8002074">点击查看代码</a>

第五题uva 10986 Sending email

<a target="_blank" href="http://uva.onlinejudge.org/index.php?option=com_onlinejudge&amp;Itemid=8&amp;page=show_problem&amp;category=24&amp;problem=1927&amp;mosmsg=Submission+received+with+ID+10629266">点击打开uva 10986</a>

1 题目给定的n最大20000,m最大50000,分析复杂度后发现只有SPFA最靠谱。

2 分析题目的样列可知,这一题是要用邻接矩阵来存储无向图,所以要注意无向图怎么存储在邻阶表中

2 连接表的横列有N项,纵列也是N项。形成的N*N项每项都被称为边结点,每项都有纵横两个坐标,例如点(N,N-1),表示的就是从第N点向第N-1点有无路径。由于有E条边,自然有E条路径,但是由于无向=双向,所以要乘以2。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8002481">点击查看代码</a>

第六题 uva 10801  Lift Hopping

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8007698">点击打开uva 10801</a>

1 有n个电梯,电梯可以到达的层数是一定的,那么我们就把楼层看成是图上的点,那么我们就可以得到的哪些点是有连通的。

2 又由于有多个电梯,所以x-&gt;y可能有多种方式,所以这就类似于重边问题那么我们要选择边权值最小的最为最后的边权值。

3 接下来图建好以后就是考虑怎么Dijkstra,由于要交换乘坐电梯,那么我们就自然的想到了图论中的换边(松弛步),那么我们就把换乘电梯看成是在换边,就是说只要做松弛步就是在换成电梯,那么这个时候就要加上等电梯的时间60s。

4 这里有个地方就是由于源点是会做松弛步的,但是源点是不用加上60s的,所以最后输出的时候要特判一下。如果k为0,直接输出0;如果k部位0,那么最后的输出要减去60。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8007698">点击查看代码</a>

第七题 hdu 2544 最短路

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2544">点击打开hdu2544</a>

思路:模板题

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8008081">点击查看代码</a>

第八题 hdu 3790 最短路径问题

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=3790">点击打开hdu 3790</a>

由于题目要求在最短路径的时候花费最少,那么这就是在做松弛操作的时候判断一下当前的选择的边的花费是不是最少的,那么这样就可以求出最少的花费。利用最短路的思想即可

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8014034">点击查看代码</a>

第九题 hdu 1548 A strange lift

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1548">点击打开hdu 1548</a>

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8045122">点击查看代码</a>

第十题 hdu 2066 一个人的旅行

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2066">点击打开hdu2066</a>

题目给定的起点有s个,终点有d个。要求找到从起点到这些终点最短的路径。很显然只要枚举起点然后比较最后得到最小的值。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8045301">点击查看代码</a>

第十一题 hdu 2112 HDU Today

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2112">点击打开hdu 2112</a>

1 题目中的起点和终点可能相同,这个时候输出0。

2 用map映射的时候用char类型,由于string是个类效率比较低。

3 处理成无向图

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8046624">点击查看代码</a>

第十二题 hdu 1217 Arbitrage

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1217">点击打开hdu 1217</a>

1 题目要求的是经过一轮的转换之后,原来的比例能够大于1。比如原先的“美元:美元 = 1:1”,最后要求能够达到“美元:美元 &gt; 1”

2 假设dis[i][j]表示“i : j”的比例,那么初始化dis[i][i] = - 1。

3 由于n最大为30,所以果断选择floyd算法。但是这里有个地方不同的是,这里并不是要求最小而是求最大,所以应该要把“小于改成大于”

4 最后只要能够找到一种货币的兑换比例大于1即满足条件

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8056444">点击查看代码</a>

第十三题 hdu 1245 Saving James Bond

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1245">点击打开hdu 1245</a>

1 题目讲的是有一个湖100x100这个人刚开始在一个直径为15的圆心在原点的园内,然后要通过跳跃的方式问我们他是否能够到达岸边。如果可以求出最短的路径和步数

2  很明确就是最短路问题。但是这个时候问题来了,起点和终点是在哪里,所以我们采用的是将原点作为起点,岸边做为终点。知道了起点和终点,我们就可以求最短路,但是这个时候会碰到另外一个问题,边的长度。对于这个问题,我们是采取的方法是将这些点分成三类。1类:起点  2类:终点  3类:其它点 ,那么我们就可以分别对这三类的点求出它和其它点的距离。

注意事项:

1 输入的数据中,点的范围可能会在园内或在湖外,所以在输入的时候要判断点是否合法。

2 这一题精度要求很严格,一些比较之类的要注意精度问题

3 注意n = 0 的情况,这里如果n = 0,但是d &gt; 42.5 是可以跳出去的。但是只要有乌龟,这个人就必须通过踩在乌龟上面跳出去,所以n = 0是比较特殊的。

4  n不大所以什么方法都可以做

5 求所需几步的时候利用一个setp[][]数组,首先初始户为0然后将可以到达的点标记为1,最后只要在更新dis[][]的时候更新即可。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8059793">点击查看代码</a>

第十四题 hdu 1535 Invitation Cards

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1535">点击打开链接</a>

1 题目要求的是总的最小的花费,意思就是要求每一个人的花费都最小。

2 由于每一个人都是从1出去,最后还是都要回到1的,那么求解的时候就要分成两部分“出去+回来”;出去的话直接利用SPFA(1),1作为起点即可求出每一点的最小花费,回来的话如果是直接利用对每一个人进行SPFA,那么这样肯定超时。仔细想想要求的是每一个点到1的最小距离,那么由于给定的是一个有向图,那么只要重新建图把边反向,那么我们所求的问题就变成1到每一个点的最小距离。所以只要两步SPFA(1)即可。

3 数据类型为long long

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8067131">点击查看代码</a>

第十五题 hdu 1546 Idiomatic Phrases Game

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1546">点击打开hdu 1546</a>

1  只要建好图,然后利用SPFA求解最短路即可。注意字符串的处理

2  定义一个char ch[10]数组,如果给数组的每一个元素值赋值后,还要记得要在最后ch[9]添加‘\0’,表示结束。就是如果要保存10个元素,那么数组最小要开到11,因为第11个表示‘\0’来表示正常结束。所以数组尽量开大点

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8067460">点击查看代码</a>

第十六题 hdu 2680 Choose the best route

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2680">点击打开hdu 2680</a>

1 题目要求的是从某一个站点能否到达目标站点

2 题目的其实站点有多个,如果都对每一个站点进行SPFA的话那么肯定TLE的。所以这个时候我们想到了增加一个新的点0,用来作为新的起点。这个时候只要把能够和0相连的点的权值标记为0即可。

3 注意这一题的图是一个有向图

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8068213">点击查看代码</a>

第十七题 hdu 2923 Einbahnstrasse

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2923">点击打开hdu 2923</a>

1 题目要求的是有n个点,然后有c个破车,这个c个破车可能在同一城市里面,现在要把这些破车统一拉到中心点1.

2 这题的中心在1点,那么所求 ans = 1-&gt;所有破车的距离之和 + 所有破车-&gt;1的之和。所以这里涉及到1-&gt;所有破车的距离 和 所有破车-&gt;1的距离,那么我们可以使用SPFA和floyd。如果使用的是floyd那么最后的ans = dis[1][i]+dis[i][1];如果是SPFA就要先求一下1-&gt;所有破车的距离之和,然后在重新建图就是把边反向然后对1点SPFA ,在加上1-&gt;所有破车的和即可。

4  点的表示,利用map映射。

3  这一题给的n虽然才100,但是利用SPFA的时候要数组记得开1010,因为c最大为1000.这个地方杭电是WA,不给RE,所以我WA了40+。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8071207">点击查看代码</a>

第十八题 hdu 3339 In Action

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=3339">点击打开hdu 3339</a>

1 这一题多了一个限制条件能量,即每一点都有一个自己的能量值。

2 问题是要求能量至少要大于1/2的情况下的最短路,最开始我理解成是贪心,然后就是无休止的的WA,后来才知道是dp。其实很好理解,对于每一个点的能量只有两种选择取或者不取,那么这就是典型的0/1背包问题。但是有一个问题就是选取什么作为背包的容量,刚开始我选择pow_sum作为背包的容量,然后距离为价值求dp,然后又是一顿WA。后来改成了以cost_sum作为背包的容量,然后pow作为价值求解dp,最后判断是否有一个

dp[i] &gt; sum/2然后就1 A了。

3 注意题目明确指出有多个坦克,意思就是每一个坦克都从0开出并且只能攻击一个点。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8074450">点击查看代码</a>

第十九题 hdu 2807 The Shortest Path

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=2807">点击打开hdu 2807</a>

1 题目明确要求x-&gt;y是否有了,而且有多次询问,所以序则floyd

2 题目给的点的形式是矩阵,所以还要去处理矩阵,判断A*B=C

3 题目说了A B C三个城市,所以做A B C三个是不同的

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8074966">点击查看代码</a>

第二十题 hdu 1595 find the longest of the shortest

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1595">点击打开hdu 1595</a>

1 题目要求的是删掉一条边之和求出的最短路中的最大值。

2 很明显,肯定是要先求出原图的最短路并且记录父亲节点。现在我们可以想,如果要枚举所有的边,显然这个是不可能的实现的。所以我们仔细分析可以知道其实能够对最短路产生影响的就是原图最短路上的边,所以我们只需要去枚举删除最短路径上面边然后求最短路即可,最后得到ans

3 这一题的n &lt;= 1000 , m&lt;=n*(n-1)/2 , 刚开始我用的SPFA,然后就开始TLE。后来知道了,有些时候SPFA的期望值中O(ke),有些题目会卡k,所以这个时候只能选择优先队列的Dij算法了。

4 题目用到了捆绑两种类型的pair&lt;int , int&gt;pii;

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8076415">点击查看代码</a>

第二十一题 hdu 1599 find the mincost route

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1599">点击打开hdu 1599</a>

1 题目要求的是能否有从某一个点出发至少经过两个不同点然后回到源点,有的话求最小路径长度。

2 题意很明确就是要求最小环问题 , 所以现在用到了floyd的一个扩展求解图上最小环。

3 &lt;&lt;floyd求解环中的最小环&gt;&gt;

   1 为什么要在更新最短路之前求最小环:

      在第k层循环,我们要找的是最大结点为k的环,而此时Dist数组存放的是k-1层循环结束时的经过k-1结点的最短路径,也就是说以上求出的最短路是不经过k点的,这就刚好符合我们的要求。为什么呢?假设环中结点i,j是与k直接相连,如果先求出经过k的最短路,那么会有这样一种情况,即:i到j的最短路经过k。这样的话就形成不了环 。

   2最小环改进算法的证明:

      一个环中的最大结点为k(编号最大),与他相连的两个点为i,j,这个环的最短长度为g[i][k]+g[k][j]+dis[i][j] (i到j的路径中,所有结点编号都小于k的最短路径长度)。根据floyd的原理,在最外层循环做了k-1次之后,dist[i][j]则代表了i到j的路径中,所有结点编号都小于k的最短路径, 综上所述,该算法一定能找到图中最小环。

   3 为什么还要value数组:

      因为dis数组时刻都在变动不能表示出原来两个点之间的距离。

   4 形成环至少要有3点不同的点,两个点是不能算环的,所以有i , j , k不同。

4 注意:hdu有时候比较特别,你使用long long的话oj给的是WA,这一题我用long long WA了,所以用int。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8079478">点击查看代码</a>

第二十二题 hdu 3986 Harry Potter and the Final Battle

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=3986">点击打开hdu 3986</a>

1 题目要求的是删除一条之和的最坏情况,并不是删除一条边之后的最短路(WA了好久不解释)。如果都可以到n,那么输入删除一条之后的最短路径。

2 利用邻阶表+优先队列优化+Dij可以做

3 father数组记录的是在原图中的1-&gt;n的最短路径中当前这个点的前一条边的编号。

4 在邻阶表里删除一条边相当于就是边的权值变为INF

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8082949">点击查看代码</a>

第二十三题 hdu 1839 Delay Constrained Maximum Capacity Path

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1839">点击打开hdu 1839</a>

1 题目要求的是在限制时间t之内,最大的容量。而题目说了最大的容量就是路径上的最小的边值。

2 这里加了一个容量,而且是要求一条边的最短。所以这里用到了二分,因为我们知道随着边长的增大能够满足的路径越来越少,所以我们只要去枚举容量即可。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8087906">点击查看代码</a>

第二十四题 hdu 3631 Shortest Path

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=3631">点击打开hdu 3631</a>

1 题目给的n &lt;= 300,而边数m&lt;=100000,并且有Q&lt;= 100000次询问。刚开始我用优先队列+Dij然后就开始TLE,然后就没然后了。

2 看了题解之后猛然发现这尼玛就是floyd,(对算法理解不透测)。我们知道floyd就是每次都拿一个中间点k来更新dis,题目中是只有标记过的点才能够使用,那么就像floyd一样只要是标记来这个点那么就可以用这个点来进行更新dis,然后如果要求两点直间的距离只要查找即可。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8090859">点击查看代码</a>

第二十五题 hdu 1869 六度分离

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1869">点击打开hdu 1869</a>

1 题目是要求所有的数据能否满足“六度分离”,那么我们就想到所有点之间的最短距离。

2 应用floyd,如果两点之间有联系那么距离标记为1,那么最后只要判断是不是每两个人之间的距离是不是都不大于7(这里为什么是7不是6自己画图).

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8091674">点击查看代码</a>

第二十六题 hdu 1224 Free DIY Tour

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1224">点击打开hdu 11224</a>

1 提要要求的最大的环,蛋并不是这么的复杂,因为第一个点的points值为0,所以其实就是求1到某一个点的最长路,其实就是最长路问题

2 注意的是在求1到某一个点的最长路的时候还要注意这个点是否能够到达1点,这个可以用一个mark数组来标记

3 可以更简单的做法就是1-n+1的最长路。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8093639">点击查看代码</a>

第二十七题 hdu 1385 Minimum Transport Cost

<a target="_blank" href="http://acm.hdu.edu.cn/showproblem.php?pid=1385">点击打开hdu 1385</a>

1 题目要求的单源的最短路,所以可以选择任意一种单源最短路来求解

2 题目还要求在路径和相同情况下要字典序小的,那么就要在更新dis数组的时候进行更新路径,如果是dis[i]&gt;tmp,那么直接更新;如果是dis[i] == tmp的情况下,那么就要求出star-&gt;i 和 star-&gt;x的路径进行比较,然后判断能否更新.

3 注意询问的时候可能问的是同一个点。

<a target="_blank" href="http://blog.csdn.net/chenguolinblog/article/details/8094659">点击查看代码</a>

继续阅读