弄懂为什么Bellman-Ford 需要n-1次循环

首先明确,不是这个算法规定了一定要n-1次循环
而是这个算法最坏的情况下需要n-1次循环。

为什么?一说就懂

什么情况下最好?
这是我们的图: 很简单的一个图,四个节点,三个边(长度分别是:3 7 12)

1 --(3)---2--(7)---3--(12)--4

让你求出,从1出发的最短路径

1 .假如题目这样描述:
1   2   3
2   3   7
3   4   12

能理解吧? (起点,终点, 长度)

关键就在于我们从上到下按顺序,把这三个边, 依次存进了 你的 edge[] 数组里面 ,对吧?
来看看Bellman算法的代码中,我们是咋操作的

  1. 先把dis 数组,起点处设置为 0 , 其它点设置为INF, dis[1] = 0 , 其他的dis[] =INF

  2. 对于每一次循环, 算法要求我们,更新 m 条边。

for(i=0;i<N-1;i++){
       for(j=0;j<G;j++){
           int u=e[j].u,v=e[j].v;
               if(d[u]!=INF&&d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v];
       }
 }

我们来动手做一下

 第一次循环。。。。。。 
 	dis[1]=0
 	dis[2] =3 ,因为  dis[1] + map[1][2] < dis[2],也就是 3 + 0 <INF
 	dis[3] = 10  ,同理
 	dis[4] = 22 , 同理
第二次循环。。。。。。。
	dis[1] =0
	dis[2] = 3
	dis[3] =10
	dis[4] = 22  ,我靠,啥都没做,
第三次循环。。。。。。
	也啥都没做

发现了吗? 我们仅仅一次循环就出结果了,谁还费那劲要做n-1 次循环????
但是,如果是这种呢?

2 .假如题目这样描述:
3   4   12
2   3   7
1   2   3

我们再动手操作一次

 第一次循环。。。。。。 
 	dis[4]=inf
 	dis[3]=inf ,
 	dis[2] =3 ,
 	dis[1]= 0 ,
第二次循环。。。。。。。
 	dis[4]=inf
 	dis[3]= 10 ,
 	dis[2] =3 ,
 	dis[1]= 0 ,
第三次循环。。。。。。
	 dis[4]=22
 	dis[3]=10,
 	dis[2] =3 ,
 	dis[1]= 0 ,

我们必须,做n-1次循环,才能出结果

原因就是:

我们按顺序存入边,
但是这个顺序有时候很好,(我们第一次循环就是从前往后循环),导致第一次循环就更新了 所有的节点
这个顺序有时候很差(我们每次都是从路径的后面向前面更新),导致每次循环仅仅更新一个

所以,我们为了应对最差情况,不得不更新n-1次。

现在你懂了为啥循环中间有个剪枝了吧,就是担心情况太好, 导致后面的循环白白浪费时间,早点剪枝跳出循环。

发布了35 篇原创文章 · 获赞 5 · 访问量 2408

猜你喜欢

转载自blog.csdn.net/qq_24884193/article/details/104357889