Wormholes
题目翻译https://vjudge.net/problem/POJ-3259#author=henuacm
思路:
本题实际上是要问是否存在负权环,spfa就可以了,正常路径是双向的,虫洞是单向的。
如果存在负环那么从1一定能回到1,一定存在负环。
ACcode:
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define met(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N = 550;
int f, n, m, p;
struct edge {int v, w;};
basic_string<edge> g[N];
int dist[N], cnt[N];
bool st[N], flag;
void spfa() {
queue<int> q;
dist[0] = 0, q.push(0), cnt[0] = 1, st[0] = true;
while (q.size()) {
int u = q.front();
q.pop();
st[u] = false;
if (flag) continue;
for (int i = 0; i < (int)g[u].size(); i++) {
int v = g[u][i].v, w = g[u][i].w;
if (dist[v] > dist[u] + w){
if (dist[v] = dist[u] + w, !st[v]) {
q.push(v);
st[v] = true;
flag |= ++cnt[v] > n + 1;
}
}
}
}
cout << (flag ? "YES\n" : "NO\n");
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> f;
while (f--) {
cin >> n >> m >> p;
flag = false;
met(dist, 0x3f), met(st, 0), met(cnt, 0);
for (int i = 0; i < n; i++) g[i].clear();
while (m--) {
int u, v, w;
cin >> u >> v >> w;
--u, --v;
g[u] += (edge) {v, w};
g[v] += (edge) {u, w};
}
while (p--) {
int u, v, w;
cin >> u >> v >> w;
--u, --v;
g[u] += (edge) {v, -w};
}
spfa();
}
return 0;
}