这题跟跟上一题思想类似,即要找一个负环,但具体实现有些不同:
1.地上的同路是双向的,但虫洞是单向的,构图需要注意。
2.这道题没有一个开始节点,但我们知道如果出现负环,那么就会一直减下去,所以开始的时候可以把所有点的距离取任意值,这也是为什么很多人写这道题根本没有数组的初始化。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 501
#define M 6000
int n;
int m;
int w;
int cnt;
struct Edge{
int s;
int e;
int t;
void set(int s, int e, int t){
this->s = s;
this->e = e;
this->t = t;
}
}edge[M];
int time[N];
bool Bellman_Ford(){
int i, j;
memset(time, 0, sizeof(time));
for(i = 1; i < n; i++){
bool flag = 0;
for(j = 0; j < cnt; j++){
int s = edge[j].s;
int e = edge[j].e;
int t = edge[j].t;
if(time[e] > time[s] + t){
flag = true;
time[e] = time[s] + t;
}
}
if(!flag) break;
}
for(i = 0; i < cnt; i++){
int s = edge[i].s;
int e = edge[i].e;
int t = edge[i].t;
if(time[e] > time[s] + t){
return true;
}
}
return false;
}
int main(){
int i, j;
int f;
scanf("%d", &f);
while(f--){
cnt = 0;
scanf("%d %d %d", &n, &m, &w);
for(i = 0; i < m; i++){
int s, e, t;
scanf("%d %d %d", &s, &e, &t);
edge[cnt++].set(s, e, t);
edge[cnt++].set(e, s, t);
}
for(i = 0; i < w; i++){
int s, e, t;
scanf("%d %d %d", &s, &e, &t);
edge[cnt++].set(s, e, -t);
}
if(Bellman_Ford()){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}