poj3259 Wormholes

Wormholes
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 29805   Accepted: 10779

Description

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ's farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..NM (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: NM, and W 
Lines 2..M+1 of each farm: Three space-separated numbers (SET) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path. 
Lines M+2..M+W+1 of each farm: Three space-separated numbers (SET) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.

Output

Lines 1..F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

Hint

For farm 1, FJ cannot travel back in time. 
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.

Source

 
解题:Bellman-Ford 算法模板题。存在负环即可以看见自己,虫洞?你懂的!
 
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <vector>
 6 #include <climits>
 7 #include <algorithm>
 8 #include <cmath>
 9 #define LL long long
10 using namespace std;
11 const int INF = INT_MAX>>1;
12 int cnt,dis[600];
13 struct ARC {
14     int u,v,w;
15 } arc[6000];
16 bool bf(int n) {
17     int i,j;
18     for(i = 2; i <= n; i++)
19         dis[i] = INF;
20     dis[1] = 0;
21     for(i = 1; i < n; i++) {
22         for(j = 0; j < cnt; j++) {
23             if(dis[arc[j].v] > dis[arc[j].u]+arc[j].w) {
24                 dis[arc[j].v] = dis[arc[j].u] + arc[j].w;
25             }
26         }
27     }
28     for(j = 0; j < cnt; j++) {
29         if(dis[arc[j].v] > dis[arc[j].u]+arc[j].w) return false;
30     }
31     return true;
32 }
33 int main() {
34     int kase,n,m,k,u,v,w,i;
35     scanf("%d",&kase);
36     while(kase--) {
37         scanf("%d %d %d",&n,&m,&k);
38         cnt = 0;
39         while(m--) {
40             scanf("%d %d %d",&u,&v,&w);
41             arc[cnt++] = (ARC) {u,v,w};
42             arc[cnt++] = (ARC) {v,u,w};
43         }
44         while(k--) {
45             scanf("%d %d %d",&u,&v,&w);
46             arc[cnt++] = (ARC) {u,v,-w};
47         }
48         bf(n)?puts("NO"):puts("YES");
49     }
50     return 0;
51 }
View Code
 解法2:SPFA算法,邻接表存储图。不过此题貌似效果不明显,还没裸的Bellman-Ford快!
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <vector>
 6 #include <climits>
 7 #include <algorithm>
 8 #include <cmath>
 9 #include <queue>
10 #define LL long long
11 using namespace std;
12 const int maxn = 510;
13 const int INF = INT_MAX>>2;
14 int n;
15 struct arc {
16     int w,to;
17 };
18 vector<arc>e[maxn];
19 bool used[maxn];
20 int num[maxn],d[maxn];
21 bool spfa(int x) {
22     int i,j,temp;
23     memset(num,0,sizeof(num));
24     memset(used,false,sizeof(used));
25     for(i = 1; i <= n; i++)
26         d[i] = INF;
27     d[x] = 0;
28     queue<int>q;
29     while(!q.empty()) q.pop();
30     used[x] = true;
31     num[x]++;
32     q.push(x);
33     while(!q.empty()) {
34         temp = q.front();
35         q.pop();
36         used[temp] = false;
37         for(i = 0; i < e[temp].size(); i++) {
38             j = e[temp][i].to;
39             if(d[j] > e[temp][i].w+d[temp]) {
40                 d[j] = e[temp][i].w + d[temp];
41                 if(!used[j]) {
42                     num[j]++;
43                     used[j] = true;
44                     if(num[j] >= n) return true;
45                     q.push(j);
46                 }
47             }
48         }
49     }
50     return false;
51 }
52 int main() {
53     int kase,i,u,v,w,m,k;
54     scanf("%d",&kase);
55     while(kase--) {
56         for(i = 0; i < maxn; i++)
57             e[i].clear();
58         scanf("%d %d %d",&n,&m,&k);
59         while(m--) {
60             scanf("%d %d %d",&u,&v,&w);
61             e[u].push_back((arc) {w,v});
62             e[v].push_back((arc {w,u}));
63         }
64         while(k--) {
65             scanf("%d %d %d",&u,&v,&w);
66             e[u].push_back((arc) {-w,v});
67         }
68         spfa(1)?puts("YES"):puts("NO");
69     }
70 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/3829305.html