这题跟跟上一题思想类似,即要找一个负环,但具体实现有些不同:
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; }