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 }
越努力,越幸运