最短路算法小结


最近在学最短路的各种算法,参考了各位菊苣的心得以及相关资料,觉得很有必要自己总结下!


Dijkstra算法:


适用于 无负权边,无环(视所求得“最短”定义而论)的图的单源最短路问题(也就是考虑一个点)。


常用 dist[i] 数组存储源点 到 i 点的距离,应用贪心的思想,每次 从 未选 点集中 选出距离已选点集最近(最优)的一个点,然后将此点加入已选点集,尝试通过此点 更新 源点 到未选点集 的距离(dist[i]数组),

即dist[i] = min( dist[i],dist[t] + w(t,i) ),其中点 t 是此时新加入已选点集的点,w(t,i) 为 点 t 到 i 的权值。


注意到程序在选择最优的点很耗时,可以借助优先队列(常用STL)进行优化,每次取队头元素操作即可,非常实用!


Bellman-ford 算法:


适用于 带负权边 的 有向图 的单源最短路问题,但图中不能包含权值总和为 负 的回路(此时无最优解),负权无向边不能处理也是这个道理。


可作为 负权 回路 是否存在的判断算法。


标准的算法思想网上一大堆,可以参考北大课件。


算法处理方法一般是边,对于一个具有 n 个顶点的图,从源点到任意顶点最多经过 不构成 负权值回路 的 n - 1条边,

那么更新对dist[i]数组的更新最多也就是n - 1次(称作 松弛),如果还能进行第n 次松弛,是否还会影响dist的值,那

么就可以判断是否存在图中存在 环,有环的情况可能在n -1 次松弛就已经发生了(影响dist的值),但并不影响结论(环可以无限更新dist),所以一般处理n-1次。


当然,如果在某次松弛n条边后,所有dist都没变,那么就可以提前结束!


思想和Dijkstra很类似,但Dijkstra算法中,某点v一旦确定了,dist[v]就不会变了,然而Bellman-ford中不一定。


SPFA算法:


Bellman-ford算法的改进版(更快)。


与Dijkstra算法优先队列实现相似,但可以通过增加updateTimes[i]数组 或者 inqe[i] 数组,来判断 顶点i 更新的次数(更新次数达到n 时存在环) 或者 是否在队列 中,来进一步优化。


建议边做题边思考

POJ  3159,2387   Dijkstra算法优先队列实现

POJ 3259,2240,1860  Bellman-ford,spfa算法模板题


Floyd算法:


尝试将 i -> j 道路 更新成 i -> k -> j ,即在 点 i 到 j 的 边,插入中间点k ,来更新 i -> j 路的长度。


思路清晰,方法简单,但要注意 枚举插入的点 k 要放在 最外层 循环!!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值