算法札记 - 带负权边的最短路径 - Bellman-Ford算法

bellman-Ford算法

核心代码部分在这里插入图片描述
栗子

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一般来说,Bellman-Ford算法只需要 n − 1 ( n 为 顶 点 数 ) n-1(n为顶点数) n1(n)松弛就可以了。在每一个阶段,我们都会对每一套边进行松弛操作,而每实施一次松弛操作,就会有一些顶点已经求得其最短路径,此后这些顶点的最短路径值就会保持不变。经过 k k k个阶段,就已经找出了从原点出发最多经过 k − 1 k-1 k1条边到达其余顶点的最短路径。

Bellman-Ford算法的时间复杂度为 O ( n m ) O(nm) O(nm),包括n次对边集合的松弛操作,边集合的大小为m.

判断负权回路

如果进行 n − 1 n-1 n1次松弛操作之后,任然存在:
在这里插入图片描述
换句话说就是在进行 n − 1 n-1 n1次松弛操作之后任然可以再继续成功地进行松弛操作,那么此图必然存在负权回路。

优化

从Bellman-Ford的时间复杂度上来看,对于多顶点的稠密图来说其效率将大大下降,因此我们给出下面两种优化方式:

  1. 在实际操作中,经常可能在为到达 n − 1 n-1 n1轮时已经得出了需要的最短路径,因此,我们可以添加一个数组用来备份 d i s [ . . . ] dis[...] dis[...]数组,如果在新一轮的松弛中 d i s [ . . . ] dis[...] dis[...]数组的值没有发生变化,即可提前调出循环。

  2. 由前文论述可知,在每一次松弛操作之后就会有一些顶点已经得到了最短路径,但是在往后每次松弛操作中还是要判断是否需要进行松弛。因此,每次仅对最短路径估计值发生了变化的顶点的所有出边进行松弛操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值