题目链接: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 }