Bellman算法。进行n-1次循环之后如果还能继续修改使dis减小,说明存在可以使时间变小的回路。
/*
Poj: 3259: Wormholes
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 32767
using namespace std;
const int M = 2705;
const int N = 505;
struct Path {
int a, b;
int t;
}edges[M*2];
int dis[N];
int f;
int n, m, w;
int total;
bool bellman();
int main()
{
//freopen("data.in", "rb", stdin);
cin >> f;
while(f--) {
cin >> n >> m >> w;
total = 0;
for(int i = 0; i < m; i++) {
cin >> edges[total].a >> edges[total].b >> edges[total].t;
total++;
edges[total].a = edges[total-1].b;
edges[total].b = edges[total-1].a;
edges[total].t = edges[total-1].t;
total++;
}
for(int i = 0; i < w; i++) {
cin >> edges[total].a >> edges[total].b >> edges[total].t;
edges[total].t = 0 - edges[total].t;
total++;
}
for(int i = 2; i < n + 1; i++) {
dis[i] = Max;
}
dis[1] = 0;
if(bellman()) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
return 0;
}
bool bellman()
{
for(int i = 0; i < n - 1; i++) {
bool flag = true;
for(int j = 0; j < total; j++) {
int v1 = edges[j].a;
int v2 = edges[j].b;
if(dis[v1] != Max && dis[v1] + edges[j].t < dis[v2]) {
dis[v2] = dis[v1] + edges[j].t;
flag = false;
}
}
if(flag)
break;
}
for(int i = 0; i < total; i++) {
int v1 = edges[i].a;
int v2 = edges[i].b;
if(dis[v1] != Max && dis[v1] + edges[i].t < dis[v2])
return true;
}
return false;
}