发现很多东西不记下来过一段时间就想不明白了,先整理一部分,嗯不对的地方请路过的同学指正~
首先,最短路径相关算法通常依赖一个重要性质,即最短路径的子路径也是最短路。证明如下:
单源最短路:
1、Bellman-Fold算法 (将权值变为相反数,可以求最长路)
数组dis[i]]记录从源点s到顶点i的路径长度,初始化数组dis[i]为正无穷, dis[s]为0;
以下操作循环执行至多n-1次,n为顶点数:
这是因为最短路从1到n,最多经过n-1条边,而最上边每一层for循环,实际上是求从源点出发,只经过k条边最短路是多少,k最多n-1
对于每一条边e(u, v),如果dis[u] + w(u, v) < dis[v],则另dis[v] = dis[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环(用flag标记优化)。否则执行下次循环;
为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在dis[u] + w(u, v) < dis[v]的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组dis[n]中记录的就是源点s到各顶点的最短路径长度。
复杂度为O(VE),最短路可以处理负环。
2、DAG(有向无环图) Shortest Path (可以求最长路)
因为是无环图,可以首先进行拓扑排序,得到一个所有点的线性排列,这一步复杂度为O(V+E)
然后根据拓扑排序的次序对每一个节点进行处理:即对从该节点出发的所有边进行松弛操作。总复杂度为O(V+E)
poj 3249
http://www.cnblogs.com/yanlingyin/archive/2011/11/12/2246716.html 最长路标记路径
3、Dijkstra (不能改为最长路)
堆优化时间复杂度可为O(N*logN)
4、SPFA (权值取负,可以求最长路)
可以处理负权边,即进队次数超过N次为出现负环。每次从队列中取点进行松弛操作。
复杂度为O(KE),一般情况下K小于等于2。
SPFA对Bellman-Ford算法优化的关键之处在于意识到:只有那些在前一遍松弛中改变了距离估计值的点,才可能引起他们的邻接点的距离估计值的改变。因此,用一个先进先出的队列来存放被成功松弛的顶点。初始时,源点s入队。当队列不为空时,取出对首顶点,对它的邻接点进行松弛。如果某个邻接点松弛成功,且该邻接点不在队列中,则将其入队。经过有限次的松弛操作后,队列将为空,算法结束。SPFA算法的实现,需要用到一个先进先出的队列 queue 和一个指示顶点是否在队列中的 标记数组 mark。为了方便查找某个顶点的邻接点,图采用临界表存储。
多源最短路:
1、Floyd算法 (可以求最长路,但是有可能存在正环最长路不存在,无法判断)
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k)
+ Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j)
= Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
最开始初始化dis[i][j]为直接相连的权值
最外层的for循环实际上表示的是:仅利用点1到点k从i到j的最短路是多少。所以三层for循环都是从点1到点n
时间复杂度O(n^3),空间复杂度O(n^2)
同时还可以加入path[]数组保存路径
http://blog.youkuaiyun.com/ll365594480/article/details/6792096
变形:floyd变形求最小环,这个链接讲的很清楚
http://www.cnblogs.com/Yz81128/archive/2012/08/15/2640940.html
例题:poj 1734
应用:
1、最短路解决差分约束问题
可行解的求法
2、单源最短路(最朴素)
3、多元起点单源目的地:反向加边处理
4、所有结对点最短路:fold-warshall
5、各算法保存最短路路径
本文整理了图论中的最短路径算法,包括Bellman-Ford、Dijkstra、SPFA等,并探讨了如何求解最长路径。这些算法在处理单源最短路、有向无环图最短路及多源最短路等问题时各有特点,其中Bellman-Ford和SPFA可以处理负权重,而Dijkstra则不能。文章还提到了Floyd算法在求解多源最短路时的应用,并讨论了它们在实际问题中的应用,如差分约束问题的解决方案。
1365

被折叠的 条评论
为什么被折叠?



