参考了很多资料,博客,看了很多对这个算法的介绍,理解了一点。
Bellman_Ford算法主要是处理权值存在负权的时候的情况复杂度,O(n*e),主要思想就是利用,如果最短路存在,则最多加入n-1条边,如果超过n-1,还可以继续松弛,就是存在负权回路。
这个题目就是判断是否存在负权回路。
1 #include <stdio.h> 2 #include <string.h> 3 #define N 100000000 4 int dis[1000],v,n; 5 struct edge//记录所有边的信息 6 { 7 int sv;//起点 8 int ev;//终点 9 int w;//权值 10 }p[10000]; 11 int Bellman_Ford()//判断是否存在负权回路 12 { 13 int i,j,z; 14 for(i = 1;i <= n-1;i ++) 15 { 16 for(j = 1;j <= v-1;j ++) 17 { 18 if(dis[p[j].ev] > dis[p[j].sv] + p[j].w)//松弛操作 19 dis[p[j].ev] = dis[p[j].sv] + p[j].w; 20 } 21 } 22 z = 1; 23 for(i = 1;i <= v-1;i ++) 24 { 25 if(dis[p[i].ev] > dis[p[i].sv] + p[i].w) 26 { 27 dis[p[i].ev] = dis[p[i].sv] + p[i].w; 28 z = 0; 29 break; 30 } 31 } 32 return z; 33 } 34 int main() 35 { 36 int t,i,m1,m2; 37 scanf("%d",&t); 38 while(t--) 39 { 40 memset(p,0,sizeof(p)); 41 v = 1; 42 scanf("%d%d%d",&n,&m1,&m2); 43 for(i = 2;i <= n;i ++)//初始化dis数组 44 dis[i] = N; 45 dis[1] = 0; 46 for(i = 1;i <= m1;i ++)//输入边信息写的有点繁琐 47 { 48 scanf("%d%d%d",&p[v].sv,&p[v].ev,&p[v].w); 49 if(p[v].sv == 1) 50 { 51 dis[p[v].ev] = p[v].w; 52 } 53 v ++; 54 p[v].sv = p[v-1].ev; 55 p[v].ev = p[v-1].sv; 56 p[v].w = p[v-1].w; 57 if(p[v].sv == 1) 58 { 59 dis[p[v].ev] = p[v].w; 60 } 61 v ++; 62 } 63 for(i = 1;i <= m2;i ++) 64 { 65 scanf("%d%d%d",&p[v].sv,&p[v].ev,&p[v].w); 66 p[v].w = -p[v].w; 67 if(p[v].sv == 1) 68 { 69 dis[p[v].ev] = p[v].w; 70 } 71 v ++; 72 } 73 if(Bellman_Ford()) 74 printf("NO\n"); 75 else 76 printf("YES\n"); 77 } 78 return 0; 79 }
很搓的SPFA+邻接矩阵。居然比上边这个慢非常多。。。JUST实验一下,以后要用正规的方式写。。。
1 #include <stdio.h> 2 #include <string.h> 3 #define N 100000000 4 int dis[10000],v,n; 5 int map[501][501]; 6 int que[1000000]; 7 int spfa() 8 { 9 int i,j,k,start,end; 10 int num[1000]; 11 int o[1000]; 12 memset(num,0,sizeof(num)); 13 memset(o,0,sizeof(o)); 14 memset(que,0,sizeof(que)); 15 que[1] = 1; 16 o[1] = 1; 17 num[1] = 1; 18 start = end = 1; 19 while(start <= end) 20 { 21 k = 1; 22 for(i = start; i <= end; i ++) 23 { 24 o[que[i]] = 0; 25 for(j = 1; j <= n; j ++) 26 { 27 if(dis[j] > dis[que[i]] + map[que[i]][j]) 28 { 29 dis[j] = dis[que[i]] + map[que[i]][j]; 30 if(!o[j]) 31 { 32 que[end + k] = j; 33 k ++; 34 num[j] ++; 35 o[j] = 1; 36 if(num[j] >= n) 37 return 1; 38 } 39 } 40 } 41 } 42 start = end + 1; 43 end = end + k - 1; 44 } 45 return 0; 46 } 47 int main() 48 { 49 int t,i,j,m1,m2,sv,ev,w; 50 scanf("%d",&t); 51 while(t--) 52 { 53 memset(map,0,sizeof(map)); 54 v = 1; 55 scanf("%d%d%d",&n,&m1,&m2); 56 for(i = 1;i <= n;i ++) 57 { 58 for(j = 1;j <= n;j ++) 59 map[i][j] = N; 60 map[i][j] = 0; 61 } 62 dis[1] = 0; 63 for(i = 2;i <= n;i ++) 64 dis[i] = N; 65 for(i = 1;i <= m1;i ++) 66 { 67 scanf("%d%d%d",&sv,&ev,&w); 68 if(map[sv][ev] > w) 69 { 70 map[sv][ev] = w; 71 map[ev][sv] = w; 72 } 73 } 74 for(i = 1;i <= m2;i ++) 75 { 76 scanf("%d%d%d",&sv,&ev,&w); 77 if(map[sv][ev] > -w) 78 { 79 map[sv][ev] = -w; 80 } 81 } 82 if(spfa()) 83 printf("YES\n"); 84 else 85 printf("NO\n"); 86 } 87 return 0; 88 }