最短路算法总结

单源最短路

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

  • SPFA(shortest path fast algorithm)

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

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

下面介绍另一种算法。

  • Dijistra

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

  • Dijistra+堆优化

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

多源最短路

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

  • Floyd

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

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

次短路算法

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


后面待更新完善……

转载于:https://www.cnblogs.com/VictoryCzt/p/10053427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值