bellman算法
John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。
--------------------------------------------------------------------
#include <iostream>
#include <math.h>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define MAXN 520
#define MAXM 6000
#define INF 0Xffffff
using namespace std ;
struct node
{
int u, v, w;
} edge[MAXM];
int T, n, m, l, u, v, w;
int dis[MAXN], ans;
int bellman()
{
for(int i=0; i<n; i++)
dis[i] = INF;
///可以写成fill(dis,did+n,INF);
dis[1] = 0;
for(int i=0; i<n; i++)
{
int flag = 0;
for(int j=0; j<ans; j++)
{
if(dis[edge[j].u]>dis[edge[j].v]+edge[j].w)///松弛
{
dis[edge[j].u]=dis[edge[j].v]+edge[j].w;
flag = 1;
}
}
if(!flag)
break;
///因为对于V个点 你最多需要进行|V|-1次外循环,如果有负环它会一直进行下去,
///但是只要进行到第V次的时候就说明存在负环了
if(i==n-1)///如果存在负边
return 1;
}
return 0;
}
void add(int u,int v,int w)
{
edge[ans].u = u;
edge[ans].v = v;
edge[ans].w = w;
ans++;
}
int main()
{
scanf("%d", &T);
while(T--)
{
ans = 0;
scanf("%d %d %d", &n, &m, &l);
for(int i=0; i<m; i++)
{
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
for(int i=0; i<l; i++)
{
scanf("%d %d %d", &u, &v, &w);
add(u, v, -w);
}
if(!bellman()) printf("NO
");
else printf("YES
");
}
return 0;
}