原题地址:http://poj.org/problem?id=3259
思路:spfa判负环的模板题
#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MOD 1e9+7
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
int t, n, m, w;
struct node {
int v, w;
node() {}
node(int v, int w): v(v), w(w) {}
};
vector<node>G[maxn];//vector存边
bool vis[maxn];
int num[maxn];
int dis[maxn];
bool spfa() {
queue<int>q;
memset(vis, 0, sizeof(vis));//判断是否在队列
memset(num, 0, sizeof(num));//记录一个点进入队列次数
memset(dis, 0x3f, sizeof(dis));//初始化距离为无穷大
q.push(1);
dis[1] = 0;
num[1]=1;
while(!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 0;
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if(dis[v] > dis[u] + G[u][i].w) {
dis[v] = dis[u] + G[u][i].w;
if(!vis[v]) {
vis[v] = 1;
q.push(v);
num[v]++;//如果一个点入队次数超过n,那么就说明有负环
if(num[v] >= n) return 1;
}
}
}
}
return 0;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &w);
for(int i = 1; i <= n; i++) {
G[i].clear();
}
for(int i = 1; i <= m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
G[a].push_back(node(b, c));
G[b].push_back(node(a, c));
}
for(int i = 1; i <= w; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
G[a].push_back(node(b, -c));
}
if(spfa()) printf("YES\n");
else printf("NO\n");
}
return 0;
}