Bellman-Ford算法(解决负权边)

本文详细解析了Bellman-Ford算法,介绍了如何处理图中的负权边,并通过实例展示了算法的运行过程。核心思想是在n-1轮迭代中对每条边进行松弛操作,以找到最短路径。同时,文章指出在n-1轮后仍能松弛说明存在负权回路,并讨论了算法的优化策略。
摘要由CSDN通过智能技术生成

核心代码:

for (int k = 1; k <= n - 1; ++k){
   
	for (int i = 1; i <= m; ++i){
   
		if(dis[v[i]] > dis[u[i]] + w[i])
			dis[v[i]] = dis[u[i]] + w[i];
	}
} 

上面的代码外层循环一共循环了n - 1次(n为顶点个数), 内层循环循环了m次(m为每一条边),即枚举每一条边。dis数组的作用与Dijkstra算法一样,是用来记录源点到其余各个顶点的最短路径的。u、v、w三个数组是用来记录边的信息的。例如:第i条边存储在u[i]、v[i]、和w[i]中, 表示从顶点u[i]到顶点v[i]这条边(u[i]->v[i])权值为w[i]。

	if(dis[v[i]] > dis[u[i]] + w[i])
		dis[v[i]] = dis[u[i]] + w[i];

上面这行代码的意思是:看看能否通过u[i]->v[i](权值为w[i])这条边,使得1号顶点到v[i]号顶点的距离(dis[u[i]])加上u[i]->v[i](权值为w[i])这条边的值是否会比原先1号顶点到v[i]号顶点的距离(dis[v[i]])要小。这一点其实是与Dijkstra算法中的“松弛”操作是一样的。现在我们要把所有的边松弛一遍,代码如下:

for (int i = 1; i <= m; ++i){
   
	if(dis[v[i]] > dis[u[i]] + w[i])
		dis[v[i]] = dis[u[i]] + w[i];
}

把每条边都松弛一遍之后会有什么效果呢?现在来举个例子。求下图1号顶点到其余各点的最短路径。
在这里插入图片描述
我们还是用一个dis数组来存储1号顶点到所有顶点的距离。
在这里插入图片描述
上方右图中每个顶点旁的值(带下划线的数字)为该顶点的最短路“估计值”(当前1号顶点到该顶点的距离),即数组dis中对应的值。根据边给出的顺序,先来处理第一条边“2 3 2”(2->3,权值为2,通过这条边进行松弛)。即判断dis[3]是否大于dis[2] + 2。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值