bellman-ford

用处:

1.解决存在负权边的最短路问题。
2.解决有边数限制的最短路问题。(此算法特有)

算法模板

memset(dis, 0x3f, sizeof dis); dis[1] = 0;
for (int i = 0; i < k; i++) // 遍历边数
{
	memcpy(backup, dis, sizeof dis); // 将上一条边的dis拷贝到backup
	for (int j = 0; j < m; j++)
	{
		int x = e[j].x, y = e[j].y, w = e[j].w; 
		dis[y] = min(dis[y], backup[x] + w); // 取1到y的最短路径
	}
}

例:

1到2的距离为1
2到3的距离为1
1到3的距离为3

在这里插入图片描述

该算法每一轮会遍历所有边但每一轮只更新一条路径的一个边
这也是为什么这个算法可以解决有边数限制的最短路问题。

第一轮

1到2的最短距离为1
1到3的最短距离为3

第二轮

1到2的距离为1
1到3的距离为2 (1到2 ,2到3)

反过来再看模板

更新最短路径

w//为一条边的权值
dis[y] = min(dis[y], backup[x] + w); // 取1到y的最短路径

注意这里有个backup数组,这个是什么?
想一想如果将代码写成这样dis[y] = min(dis[y], dis[x] + w); 会发生什么?

注意一下算法原理:每一轮会遍历所有边但每一轮只更新一条路径的一个边

每一轮会遍历所有边,如果是这么写dis[y] = min(dis[y], dis[x] + w);
拿上面例子举例:(距离初始化为无穷)
第一轮更新1到2的最短距离的d[2]此时d[2] 不为无穷。
遍历所有边,当遍历到2到3时此时,d[2]不为无穷,d[3] = d[2] + w(初始化时d[3] 无穷)
这一轮更新了一条路径的两条边,这就违背了算法原理:每一轮只更新一条路径的一个边

backup数组为上一轮dis数组的值。

第一轮dis更新,不会涉及到backup数组。
第一轮后d[2] = 1,d[3] = 3;此时第二轮backup数组的值为backup[2] = 1,backup[3] = 3
第二轮看代码dis[y] = min(dis[y], backup[x] + w);
更新1到3的最短路dis[3] = backup[2] + 1 = 3;(2到3的权值w=1)

理解:每一轮在上一轮的基础上更新一条路径的一个边,每次跟新路径时,不影响这条路径后面的路径,确保每轮只更新一条路径的一个边。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值