POJ-3259 Wormholes---SPFA判断有无负环

题目链接:

https://vjudge.net/problem/POJ-3259

题目大意:

农夫约翰在探索他的许多农场,发现了一些惊人的虫洞。虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径,W(1≤W≤200)个虫洞。FJ作为一个狂热的时间旅行的爱好者,他要做到以下几点:开始在一个区域,通过一些路径和虫洞旅行,他要回到最开时出发的那个区域出发前的时间。也许他就能遇到自己了:)。为了帮助FJ找出这是否是可以或不可以,他会为你提供F个农场的完整的映射到(1≤F≤5)。所有的路径所花时间都不大于10000秒,所有的虫洞都不大于万秒的时间回溯。

思路:

注意一开始给的通道为正常通道,是双向通道,后来给的通道是单向通道虫洞,建出图后用SPFA判断有无负环即可

也可以用Floyd

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 using namespace std;
12 typedef long long ll;
13 const int maxn = 500 + 10;
14 const int INF = 0x3f3f3f3f;
15 int T, n, m, cases, tot;
16 struct edge
17 {
18     int u, v, w;
19     edge(int u, int v, int w):u(u), v(v), w(w){}
20 };
21 vector<edge>e;
22 vector<int>G[maxn];
23 void init()
24 {
25     for(int i = 0; i <= n; i++)G[i].clear();
26     e.clear();
27 }
28 void addedge(int u, int v, int w)
29 {
30     e.push_back(edge(u, v, w));
31     tot = e.size();
32     G[u].push_back(tot - 1);
33 }
34 bool vis[maxn];
35 int cnt[maxn], d[maxn];
36 bool bellman(int u)
37 {
38     queue<int>q;
39     memset(vis, 0, sizeof(vis));
40     memset(cnt, 0, sizeof(cnt));
41     for(int i = 0; i <= n; i++)d[i] = INF;
42     d[u] = 0;
43     vis[u] = 1;
44     q.push(u);
45     while(!q.empty())
46     {
47         int u = q.front();
48         q.pop();
49         vis[u] = 0;//取出队列
50         for(int i = 0; i < G[u].size(); i++)
51         {
52             int v = e[G[u][i]].v;
53             int w = e[G[u][i]].w;
54             if(d[u] < INF && d[v] > d[u] + w)
55             {
56                 d[v] = d[u] + w;
57                 if(!vis[v])
58                 {
59                     q.push(v);//松弛成功,加入队列
60                     vis[v] = 1;//添加入队标记
61                     if(++cnt[v] >= n)return true;//存在负环
62                 }
63             }
64         }
65     }
66     return false;
67 }
68 int main()
69 {
70     cin >> T;
71     int w, x, y, z;
72     while(T--)
73     {
74         cin >> n >> m >> w;
75         init();
76         for(int i = 0; i < m; i++)
77         {
78             scanf("%d%d%d", &x, &y, &z);
79             addedge(x, y, z);
80             addedge(y, x, z);
81         }
82         for(int i = 0; i < w; i++)
83         {
84             scanf("%d%d%d", &x, &y, &z);
85             addedge(x, y, -z);
86         }
87         if(bellman(1))cout<<"YES"<<endl;
88         else cout<<"NO"<<endl;
89     }
90     return 0;
91 }

 

posted @ 2018-04-07 13:07  _努力努力再努力x  阅读(154)  评论(0编辑  收藏  举报