题目链接:https://vjudge.net/problem/POJ-3259
有n个农场,有m条路(双向)连接这些农场,又有w条虫洞(单向且负权)连接农场
问是否可以在某一点出发,然后在出发时间前回到出发点
简单来说就是找负环,这里用bellman-ford算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int N=500+5;
const int M=5200+5;
const int inf=0x7f7f7f7f;
struct edge
{
int a,b;
int c;
edge(){}
edge(int aa,int bb,int cc)
{
a=aa;b=bb;c=cc;
}
}e[M];
int n,m,w;
int d[N],cnt;
bool BF()
{
memset(d,inf,sizeof(d));
d[1]=0;
for(int i=1;i<n;i++)
{
bool flag=false;
for(int j=0;j<cnt;j++)
{
if(d[e[j].b]>d[e[j].a]+e[j].c)
{
d[e[j].b]=d[e[j].a]+e[j].c;
flag=true;
}
}
if(!flag) return false;
}
for(int j=0;j<cnt;j++)
if(d[e[j].b]>d[e[j].a]+e[j].c)
return true;
return false;
}
int main()
{
int T;
scanf("%d",&T);
int a,b,c;
while(T--)
{
cnt=0;
scanf("%d%d%d",&n,&m,&w);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[cnt++]=edge(a,b,c);
e[cnt++]=edge(b,a,c);
}
for(int i=0;i<w;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[cnt++]=edge(a,b,-c);
}
if(BF()) printf("YES\n");
else printf("NO\n");
}
return 0;
}