代码1:
/*
bellman-ford算法适合单源路径算法,和负权回路。
因此算法核心就是松弛操作
*/
1 /* 2 bellman-ford算法适合单源路径算法,和负权回路。 3 */ 4 # include<stdio.h> 5 # include <string.h> 6 using namespace std; 7 int d[1001]; //源点到各点权值 8 int max_w=10001; //无穷远 9 struct node 10 { 11 int s; 12 int e; 13 int t; 14 }edge[5200]; 15 int N,M,W_h; 16 int all_e; //所有的边数。 17 bool bellman() 18 { 19 bool flag; 20 for(int i=0;i<N-1;i++) //为什么是N-1,因为对于N个结点的图最多有N-1个结点可能对其执行松弛操作。 21 { 22 flag=false; 23 for(int j=0;j<all_e;j++) 24 if(d[edge[j].e] > d[edge[j].s] + edge[j].t) 25 { 26 d[edge[j].e] = d[edge[j].s] + edge[j].t; 27 flag=true; //relax对路径有更新 28 } 29 if(!flag) 30 break; //只要某一次relax没有更新,说明最短路径已经查找完毕, 31 //或者部分点不可达,可以跳出循环(releax),或者直接返回false。 32 } 33 // if(!flag) 34 // return false; 35 for(int k=0;k<all_e;k++) //如果还能进行松弛操作,说明有负权回路。 36 if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t) 37 return true; 38 return false; 39 } 40 int main(void) 41 { 42 int u,v,w; 43 int F; 44 cin>>F; 45 while(F--) 46 { 47 memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通 48 cin>>N>>M>>W_h; 49 all_e=0; 50 //双向边赋值。 51 for(int i=1;i<=M;i++) 52 { 53 cin>>u>>v>>w; 54 edge[all_e].s=edge[all_e+1].e=u; 55 edge[all_e].e=edge[all_e+1].s=v; 56 edge[all_e++].t=w; 57 edge[all_e++].t=w; 58 } 59 //单向边赋值。 60 for(int j=1;j<=W_h;j++) 61 { 62 cin>>u>>v>>w; 63 edge[all_e].s=u; 64 edge[all_e].e=v; 65 edge[all_e++].t=-w; //注意权值为负 66 } 67 if(bellman()) 68 cout<<"YES"<<endl; 69 else 70 cout<<"NO"<<endl; 71 } 72 return 0; 73 }