1 /**
2 problem: http://poj.org/problem?id=3259
3 spfa判负环:
4 当有个点被松弛了n次,则这个点必定为负环中的一个点(n为点的个数)
5 spfa双端队列优化:
6 维护队列使其dist小的点优先处理
7 **/
8 #include<stdio.h>
9 #include<deque>
10 #include<algorithm>
11 using namespace std;
12
13 class Graphics{
14 const static int MAXN = 505;
15 const static int MAXM = 2505 * 2 + 205;
16 const static int INF = 0x7fffffff;
17 private:
18 struct Edge{
19 int to, dist, next;
20 }edge[MAXM];
21 int first[MAXN], sign, sumOfPoint;
22 public:
23 void init(int n){
24 sumOfPoint = n;
25 for(int i = 1; i <= n; i ++){
26 first[i] = -1;
27 }
28 sign = 0;
29 }
30 void addEdgeOneWay(int u, int v, int w){
31 edge[sign].dist = w;
32 edge[sign].to = v;
33 edge[sign].next = first[u];
34 first[u] = sign ++;
35 }
36 void addEdgeTwoWay(int u, int v, int w){
37 addEdgeOneWay(u, v, w);
38 addEdgeOneWay(v, u, w);
39 }
40 bool spfaNegRing(int start){
41 bool *vis = new bool[sumOfPoint+1];
42 int *dist = new int[sumOfPoint+1];
43 int *cnt = new int[sumOfPoint+1];
44 for(int i = 1; i <= sumOfPoint; i ++){
45 vis[i] = 0;
46 cnt[i] = 0;
47 dist[i] = INF;
48 }
49 deque<int> que;
50 que.push_front(start);
51 dist[start] = 0;
52 vis[start] = 1;
53 while(!que.empty()){
54 int now = que.front();
55 que.pop_front();
56 vis[now] = 0;
57 for(int i = first[now]; i != -1; i = edge[i].next){
58 int to = edge[i].to, eDist = edge[i].dist;
59 if(dist[now] + eDist < dist[to]){
60 dist[to] = dist[now] + eDist;
61 cnt[to] ++;
62 if(cnt[to] >= sumOfPoint) { /// 如果这个点已经松弛n次则它必定是负环中的一个点
63 delete []vis; delete []dist; return true;
64 }
65 if(!vis[to]){
66 vis[to] = 1;
67 if(que.empty() || dist[to] <= dist[que.front()])
68 que.push_front(to);
69 else
70 que.push_back(to);
71 }
72 }
73 }
74 }
75 delete []vis; delete []dist; return false;
76 }
77 }graph;
78
79 int main(){
80 int f;
81 scanf("%d", &f);
82 while(f --){
83 int n, m, w;
84 scanf("%d%d%d", &n, &m, &w);
85 graph.init(n);
86 while(m --){
87 int s, e, t;
88 scanf("%d%d%d", &s, &e, &t);
89 graph.addEdgeTwoWay(s, e, t);
90 }
91 while(w --){
92 int s, e, t;
93 scanf("%d%d%d", &s, &e, &t);
94 graph.addEdgeOneWay(s, e, -t);
95 }
96 printf("%s\n", graph.spfaNegRing(1) ? "YES" : "NO");
97 }
98 return 0;
99 }