poj3259 Wormholes【Bellman-Ford或 SPFA判断是否有负环 】

题目链接:poj3259 Wormholes

题意:虫洞问题,有n个点,m条边为双向,还有w个虫洞(虫洞为单向,并且通过时间为倒流,即为负数),问你从任意某点走,能否穿越到之前。

贴个SPFA代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<string>
 6 #include<stack>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<map>
11 #include<cmath>
12 using namespace std;
13 #define lson rt*2
14 #define rson rt*2+1
15 #define CLR(a, b) memset((a), (b), sizeof((a)))
16 typedef long long ll;
17 typedef unsigned long long ull;
18 typedef pair<int, int>pii;
19 const double inf = 0x3f3f3f3f;
20 const int N = 505;
21 const int M = 2500*2+205;
22 struct node {
23     int u, v;
24     int t;
25     int nex;
26 }edge[M];
27 int head[N];
28 
29 int d[N];
30 int vis[N];
31 
32 int n, m, w;
33 
34 int spfa(int x) {
35     int i, j, k;
36     queue<int> q;
37     d[x] = 0;
38     vis[x] = 1;
39     q.push(x);
40     while(!q.empty()) {
41         int u = q.front(); q.pop();
42         vis[u] = 0;
43         for(i = head[u]; ~i; i = edge[i].nex) {
44             if(d[edge[i].v] > d[u] + edge[i].t) {
45                 d[edge[i].v] = d[u] + edge[i].t;
46                 if(!vis[edge[i].v]) {
47                     vis[edge[i].v] = 1;
48                     q.push(edge[i].v);
49                 }
50             }
51         }
52         if(d[x] < 0) return 1;//存在负权环
53     }
54     return 0;
55 }
56 int main() {
57     int t, i;
58     scanf("%d", &t);
59     while(t--) {
60         scanf("%d%d%d", &n, &m, &w);
61        
62         for(i = 1; i <= n; ++i) head[i] = -1;
63        
64         for(i = 1; i <= 2*m; i += 2) { //普通路 双向
65             scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].t);
66             edge[i].nex = head[edge[i].u];
67             head[edge[i].u] = i;
68 
69             edge[i+1].u = edge[i].v;
70             edge[i+1].v = edge[i].u;
71             edge[i+1].t = edge[i].t;
72             edge[i+1].nex = head[edge[i].v];
73             head[edge[i].v] = i+1;
74         }
75         for(; i <= 2*m+w; ++i) {//虫洞 单向
76             scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].t);
77             edge[i].t = -edge[i].t;
78             edge[i].nex = head[edge[i].u];
79             head[edge[i].u] = i;
80         }
81         
82         for(i = 1; i <= n; ++i) {
83             d[i] = inf;
84             vis[i] = 0;
85         }
86         int f = 0;
87         for(i = 1; i <= n; ++i) {
88             if(d[i] == inf) {//图可能不连通
89                 if(spfa(i)) {f = 1; break;}
90             }
91         }
92         if(f) puts("YES");
93         else puts("NO");
94     }
95     return 0;
96 }
63ms
原文地址:https://www.cnblogs.com/GraceSkyer/p/6534286.html