POJ Wormholes 最短路径 ballman_ ford 有负环

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <queue>
 6 #define MAX 9999999
 7 
 8 using namespace std;
 9 
10 struct node
11 {
12     int u, v, w;//u 为起点,v为终点,w为u—>v的权值
13 };
14 node edge[5203];
15 int n, m;//n 点数   m 边数
16 
17 bool bellman_ford()
18 {
19     int i, j;
20     bool flag;
21     int dis[503];//保存最短路径
22 
23     fill(dis,dis+n,MAX);//初始化
24     dis[1] = 0;//因为判断是否有负环,对整个图而言,So  s = 1;
25     //
26     for(i=1;i<n;i++)//共需进行|V|-1次
27     {
28         flag = false;//优化   初始化为假
29         for(j=0;j<m;j++)//对每一条边
30         {
31             // if  u.d>v.d+w(u,v) , u.d = v.d+w(u,v);
32             if(dis[edge[j].u]>dis[edge[j].v]+edge[j].w){//进行松弛
33                 dis[edge[j].u] = dis[edge[j].v]+edge[j].w;//松弛操作成功
34                 flag = true;//松弛成功变为真
35             }
36         }
37         if(!flag)//若每条边没有松弛
38             break;//跳出循环
39     }
40     // 
41     for(i=0;i<m;i++)
42         if(dis[edge[i].u]>dis[edge[i].v]+edge[i].w)//进行|V|-1次操作后  有边还能进行松弛  说明
43             return true;//存在负环
44     return false;//不存在负环
45 }
46 
47 int main()
48 {
49     int t, k, i;
50 
51     scanf("%d",&t);//输入测试数据的组数
52     while(t-- && scanf("%d %d %d",&n,&m,&k)){//输入点数,正边数,负边数
53         for(i=0;i<m;i++)
54         {
55             scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);//输入u,v,w;
56             edge[i+m].u = edge[i].v;//双向
57             edge[i+m].v = edge[i].u;//双向
58             edge[i+m].w = edge[i].w;//双向
59         }
60         m <<= 1;//正边为双向 所以m = m*2;
61         for(i=m;i<m+k;i++)
62         {
63             scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);//存负边数(单向)
64             edge[i].w = -edge[i].w;//负边就要是负的
65         }
66         m += k;//单向,So不需要*2
67         printf("%s\n",bellman_ford()?"YES":"NO");//输出结果
68     }
69     return 0;
70 }
View Code

 

题目大意: 第一行 输入一个数  是表示几组测试数据

    第二行  三个数 N(点的个数),M(正边的个数),W(负边的个数) 注意 :正边为双向的,负边为单向的。

    然后 M行u,v,w;

    再然后W行u,v,w;

    求这个图是不是存在负环。 有 YES 没NO。

若没有负环外循环最多进行|V|-1次即可,就可得到最短路径,那么若存在负环,则第|V|次操作还改变D数组,则有负环。

负环即回路中权值相加为负数。   如果陷入负环中,环中的顶点最短路径就会陷入死循环,无限变小,不会停下。。。

 

这题废物了我两天,不过也值了。O(∩_∩)O~。。

posted on 2016-01-30 23:18  青春的梦想付诸行动  阅读(376)  评论(0编辑  收藏  举报

导航