POJ-3259 Wormholes (ballman_ford 判负环)

ballman_ford 是对单源点到任意点最短路的处理方法(可以含负权边)。

对所有边进行n-1次循环,(n为点得个数),如果此时源点到这条边终点的距离 大于 源点到这条边起点的距离加上路得权值就进行更新。

题目链接

题意:FJ农场主有F个农场, 在每个农场内有 N个点, M条双向路, W个单向虫洞, 每条路需要消耗一定的时间, 每个虫洞可以使得自己回到几秒前, 现在问FJ农场主可不可以遇到以前的自己。

题解: ballman_ford 判断负环, 存在负环就说明可以, 不存在就不可以。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int INF = 0x3f3f3f3f;
 5 const int N = 505, M = 2505, W = 205;
 6 struct Node
 7 {
 8     int u, v, d;
 9 }e[M*2+W];
10 int dis[N];
11 int cnt = 0, n, m, w;
12 void add(int u, int v, int d)
13 {
14     e[cnt].u = u;
15     e[cnt].v = v;
16     e[cnt++].d = d;
17 }
18 bool ballman_ford()
19 {
20     memset(dis, INF, sizeof(dis));
21     dis[1] = 1;
22     for(int i = 1; i < n; i++)
23         for(int j = 0; j < cnt; j++)
24             {
25                 if(dis[e[j].v] > dis[e[j].u] + e[j].d )
26                 {
27                     dis[e[j].v] = dis[e[j].u] + e[j].d;
28                 }
29             }
30     bool flag = 1;
31     for(int i = 0; i < cnt; i++)
32     {
33         if(dis[e[i].v] > dis[e[i].u] + e[i].d)
34         {
35             flag = 0;
36             break;
37         }
38     }
39     return flag;
40 }
41 int main()
42 {
43     ios::sync_with_stdio(false);
44     cin.tie(0);
45     cout.tie(0);
46     int T;
47     cin >> T;
48     while(T--)
49     {
50         cnt = 0;
51         cin >> n >> m >> w;
52         int u, v, d;
53         for(int i = 0; i < m; i++)
54         {
55             cin >> u >> v >> d;
56             add(u, v, d);
57             add(v, u, d);
58         }
59         for(int i = 0; i < w; i++)
60         {
61             cin >> u >> v >> d;
62             add(u, v, -d);
63         }
64         if(!ballman_ford()) cout << "YES
";
65         else cout << "NO
";
66     }
67     return 0;
68 }
原文地址:https://www.cnblogs.com/MingSD/p/8417371.html