最短路算法总结

单源最短路

顾名思义就是寻找一个源点到其它的点的最短路,暴力的dfs或者bfs就不说了,下面讲讲几种单源最短路的算法。

  • SPFA(shortest path fast algorithm)

这个算法的实质就是利用bfs,我们先将源点到源点的距离设置为0,到其它的距离设置为无穷大(一般0x7fffffff),然后将源点加入队列,用队首的点去bfs,更新它能到达且能更新的的点,然后将未进入队列的点加入队列以备后续更新使用,然后将已经出队的点标记消掉,不断这样进行这个操作(这个也就是松弛操作),最后无法再更新任何一个点时,队列为空,最短路也就找完了,理论复杂度为 O(kn) O ( k n ) k k 为进队次数,一般k常数。

这个算法在一般的图和随机图上面运行效果良好,但是在一些精心构造的图上面就会卡到复杂度上限 O(nm) O ( n m ) (每个点进队m次)。

下面介绍另一种算法。

  • Dijistra

这个算法同样是用bfs,每次找到距离源点最近的且未被用过的点,然后拿它去更新其它点,而这个点以后再也不会被更新到(除非有负环,那么普通的Dijistra就无法使用),这样每个点只会用来更新一次其它点,每次寻找最近的点暴力复杂度为 O(n) O ( n ) ,然后更新的复杂度为它的度数(一般看作常数,除非菊花图),所以复杂度总的来说为 O(n2) O ( n 2 )

  • Dijistra+堆优化

我们发现上述的算法中,有一个寻找最近点的 O(n) O ( n ) ,可以拿一个数据结构维护,将 O(n) O ( n ) 降到 O(logn) O ( l o g n ) ,那么维护最小值我们可以简单的使用堆(自己手打或者STL的优先队列),那么该算法就被优化到了 O(nlogn) O ( n l o g n ) ,虽然一般图和随机图跑的没有SFPA快,但是在精心构造的图上面,它复杂度的优秀性就体现出来了。(NOI2018的day1T1可以说明)

多源最短路

多源最短路,就是求图上的每一个点到其它点的最短距离,朴素简单的想法就是跑 n n 遍单源最短路算法,但是这里还有其它的算法可以解决这个问题。

  • Floyd

这个算法实质上是利用了动态规划,DP的思想,我们定义如下状态f[i][j],表示 ij i ⇒ j 的最短路长度,然后我们枚举一个中转点 k k ,用它去不断更新其它情况,转移方程为f[i][j]=min(f[i][j],f[i][k]+f[k][j])。这样 n3 n 3 就可以求出多源最短路。(其实似乎跑 n n 边Dijistra+堆优化好像才O(n2logn)的复杂度,不过Floyd的常数明显较小)。

这个算法还有个用途,其实从它的转移上都可以看出,我们可以求必须经过某个点的多源最短路,这时就不用枚举中转点,而是已知中转点,然后去更新答案,复杂度为 O(n2) O ( n 2 )

次短路算法

A-star(A*)启发式搜索算法,原理是dfs时利用一个估计函数来剪枝。


后面待更新完善……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VictoryCzt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值