题解:本题主要考查Bellman-Ford求负环。
简要题意:N个点的图,2M条正权双向边,W条负权单向边。问图中是否存在负环?
1.Bellman-Ford:求负环用Bellman-Ford就行了,加上优化没有松弛则提前退出循环,减少时间。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
struct E
{
int start,to,ans;
}e[568791];
int d[568791];
int n,m,w,t,check,flag,a,b,c;
int main()
{
cin>>t;
for(int ii=1;ii<=t;ii++)
{
memset(d,0x3f3f3f3f,sizeof(d));
memset(e,0,sizeof(e));
cin>>n>>m>>w;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;//输入好坑
e[i].start=e[i+m].to=a;
e[i].to=e[i+m].start=b;
e[i].ans=e[i+m].ans=c;
}
m*=2;
for(int i=1;i<=w;i++)
{
cin>>a>>b>>c;
e[i+m].start=a;
e[i+m].to=b;
e[i+m].ans=-c;
}
d[1]=0;
for(int i=1;i<=n-1;i++)
{
check=0;
for(int j=1;j<=m+w;j++)
if(d[e[j].start]+e[j].ans<d[e[j].to])
{
d[e[j].to]=d[e[j].start]+e[j].ans;
check=1;
}
if(check==0)break;
}
flag=0;
for(int i=1;i<=m+w;i++)
if(d[e[i].start]+e[i].ans<d[e[i].to])flag=1;
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}