Dijkstra 和 Bellman-Ford算法以及spfa判断负环路

在说bellman_ford算法前,先解释dijkstra算法的思想

我们用 dis[ ] 数组来存放 i 点到起点的最短距离

1、首先它是从起点开始,广度遍历,逐层更新,靠近起点的先被确定最终距离

2、如果我们要更新 dis[y] 的最短距离,则一定用比它距离要短的 dis[x] 来更新

   如果dis[y]为全局最短,则dis[y] 不会再被更新,因为没有更短的 dis[x]值可以来更新它

3、那我们每次找全局最短的距离 dis[x] 来更新dis[y] 

 为什么dis[] 数组中最小的值就一定是i 点的最短距离

  因为我们是从起点开始广度遍历,那么所有的未知点一定是由已知点进行更新的,即dis[ 未知点 ] > dis[已知点]

  所以不会通过未知点再次更新已知点的距离,只用在已知点中找到最小的,即为最短距离

  为什么一定要用全局最短?

 全局最短的距离是确定的,不会再被更新,所以连上的边也是确定的,不会再被更改

  如果不是全局最短,此时用此点( 设为u )去更新其他点,而u更新其他点(设为y)一次后,u就不会再次用来更新

  而u再次被缩小时,y就不会再次更新

4、贪心求解,每次 dis[] 数组中更新后的值,不一定就是最优解

以一个例子做总结

假设此时 dis[v] 已经是全局最短,那么如果过v 点到达u点的最短距离也就确定

如果接下来是dis[x] 最短,那么过x 点到u 的最短距离也确定

接着是y。。。

u的最短距离即为它们的minn值

如果v确定后 dis[u] 为全局最短,说明dis[x] 和dis[y] 比dis[u] 长,自然就不用它们再更新

bellman_ford

思想:每次对所有的边进行松弛,每次可以确定一个点的最短距离,但不知道是哪个点,循环n-1,就可以确定所有的点

  • 为什么每次松弛就可以确定一个点的最短距离?

其实与dijkstra一样的思想,只不过dijkstra是每次确定一个最短距离点,并用这个点去更新其他与之相连的边

而bellman_ford是每次更新所有的边,自然就包括最短距离点到与之相连边,那么每次也都是可以产生最短距离点,

只不过最短距离点并不知道是哪个点。并且,如果存在边权为负,最短距离点可能会再次更新

而dijkstra一旦确定最短距离点就不会再更改

  • 为什么dijkstra不能处理负权边

此时1->3 的最短路应该为1-> 2 ->3, 而dijkstra 则在第一轮的遍历中就直接确定1->3 的最短距离为1,并且不会再更改

所以结果是错的

(对于环路,如果权值和为负,则每走一圈,最短距离就会缩小,如果回路权值和为正,多走一圈就会增加一圈的值)

spfa判断负环路

https://blog.csdn.net/forever_dreams/article/details/81161527

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法Bellman-Ford算法都是用于解决图中单源最短路径问题的经典算法Dijkstra算法是一种贪心算法,用于求解从给定源节点到其他所有节点的最短路径。算法通过维护一个优先队列(或最小堆)来选择当前距离源节点最近的节点,并逐步扩展路径长度最短的节点。具体步骤包括:初始化源节点的距离为0,将其加入优先队列;从队列中取出距离最小的节点,并对其相邻节点进行松弛操作,更新其距离;重复上述步骤直到队列为空。 Bellman-Ford算法是一种动态规划算法,可以处理带有权边的图。算法通过对所有边进行V-1轮松弛操作来逐步求解最短路径。具体步骤包括:初始化源节点距离为0,其他节点距离为正无穷;迭代V-1轮,对所有边进行松弛操作,即尝试通过更新边权值来缩短源节点到其他节点的距离;检测是否存在权回路,如果存在则说明图中存在无限权路径。 两者的主要区别在于: - Dijkstra算法要求图中边权值非,而Bellman-Ford算法可以处理带权边的情况。 - Dijkstra算法的时间复杂度为O((V + E)logV),其中V为节点数量,E为边数量;而Bellman-Ford算法的时间复杂度为O(VE),在稀疏图中效率较低。 选择使用哪种算法取决于具体的问题场景和图的特性。如果图中不存在权边,且需要求解单源最短路径,Dijkstra算法是一个较好的选择。而如果图中可能存在权边,并且需要检测权回路,或者只需求解单源最短路径且图较稠密,可以考虑使用Bellman-Ford算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值