剪开黑夜

In the twilight of every early morning

导航

POJ3259 Wormholes

Posted on 2019-01-05 22:32  剪开黑夜  阅读(149)  评论(0编辑  收藏  举报

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.
 
『题解』
存在负权边时不能用Dijkstra算法求最短路。本题采用Bellman-Ford最短路算法判断负权回路。模板题冲冲冲。
 
『C++』
 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 #define INF 0x7fffffff
 5 
 6 int FieldsN, dist[3000];
 7 
 8 struct Edge
 9 {
10     int s, e;
11     int t;
12     Edge() {}
13     Edge(int _s, int _e, int _t) :
14         s(_s), e(_e), t(_t) {}
15 };
16 
17 vector<Edge> edges;
18 
19 bool Bellmen_Ford(int v)
20 {
21     int s, e, t;
22     int Size = edges.size();
23 
24     for (int k = 1; k <= FieldsN; k++)
25         dist[k] = INF;
26     dist[v] = 0;
27     for (int k = 1; k < FieldsN; k++) {
28         for (int i = 0; i < Size; i++) {
29             s = edges[i].s;
30             e = edges[i].e;
31             t = edges[i].t;
32             if (dist[s] != INF && dist[s] + t < dist[e])
33                 dist[e] = dist[s] + t;
34         }
35     }
36     for (int i = 0; i < Size; i++) {
37         s = edges[i].s;
38         e = edges[i].e;
39         t = edges[i].t;
40         if (dist[s] + t < dist[e]) return true;
41     }
42     return false;
43 }
44 
45 int main()
46 {
47     int F, M, W, S, E, T;
48 
49     cin >> F;
50     while (F--) {
51         edges.clear();
52         cin >> FieldsN >> M >> W;
53         while (M--) {
54             cin >> S >> E >> T;
55             edges.push_back(Edge(S, E, T));
56             edges.push_back(Edge(E, S, T));
57         }
58         while (W--) {
59             cin >> S >> E >> T;
60             edges.push_back(Edge(S, E, -T));
61         }
62 
63         if (Bellmen_Ford(1)) printf("YES\n");
64         else printf("NO\n");
65     }
66 
67     //system("pause");
68     return 0;
69 }