Bellman-Ford最短路径

摘要:
=te[i]){28check=1;29break;30}31}32 ifbreak;///在新一轮放松中,我们发现所有点的dis值没有改变,这表明所有点都放松了33}34intflag=0;35,36时差=1;///当松弛完成时,如果能够找到可以进一步松弛的边,则意味着存在负权重边。我们通常使用此方法检查是否存在负权重循环37ifcout˂˂“此图包含负权重循环”;38其他{3940输出˂˂dis[i]˂˂“”;41cout˂˂endl;42}43}44}视图代码

对于前面说到的最短路径的求解方法,不能解决负权边的情况,而Bellman-Ford却可以

共有n个顶点,m条边,每次输入u[i],v[i],w[i],代表从u[i]到v[i]的距离是w[i],对于所有的顶点进行n-1次松弛

更多详细的内容在代码中会讲解,大家还是直接看代码吧^...^

Bellman-Ford最短路径第1张Bellman-Ford最短路径第2张
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 const int inf=99999999;
 6 using namespace std;
 7 int main()
 8 {
 9     int u[105],v[105],dis[105],w[105],te[105];
10     int m,n;
11     while(cin>>n>>m){
12         for(int i=1;i<=m;i++){
13             cin>>u[i]>>v[i]>>w[i];
14         }
15         for(int i=1;i<=n;i++)
16 
17             dis[i]=inf;///初始值设为无穷大,这样就会从第一个结点开始逐渐松弛,向后面的结点开始扩展
18         dis[1]=0;///将原点设为1
19         for(int i=1;i<=n-1;i++){
20                 for(int k=1;k<=n;k++)te[k]=dis[k];///这里把dis的初始值记录在te数组中,以便在后面我们判断是否所有的点都已经松弛完成,我们知道这个算法的最坏的情况是要松弛n-1次,但是在实际中很多情况我们提前就已经松弛完成啦,在这里加入这一步可以提前退出循环
21             for(int j=1;j<=m;j++){
22                 if(dis[v[j]]>dis[u[j]]+w[j])
23                     dis[v[j]]=dis[u[j]]+w[j];
24             }
25         int check=0;
26         for(int i=1;i<=n;i++){
27             if(dis[i]!=te[i]){
28                 check=1;
29                 break;
30             }
31         }
32         if(check==0)break;///当在新一轮的松弛中我们发现所有点的dis值都没有改变,这就表明所有的点都已经松弛完成啦
33         }
34         int flag=0;
35         for(int i=1;i<=m;i++)
36             if(dis[v[i]]>dis[u[i]]+w[i])flag=1;///当松弛完毕后如果还能找到可以继续松弛的边的话就代表含有负权边,我们通常用这种方法检查是否含有负权回路
37         if(flag==1)cout<<"此图含有负权回路";
38         else {
39 
40             for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
41             cout<<endl;
42         }
43     }
44 }
View Code

免责声明:文章转载自《Bellman-Ford最短路径》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇持续测试 | 测试流程提效:在 CODING 中实践迭代内的持续测试异步获取CMD命令行输出内容下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章