地址:https://www.luogu.com.cn/problem/P3385
解析:
直接Bellman_ford,然后再遍历一遍,如果还能松弛,那么就说明有负权回路。
但是题里问的是顶点1能到达的负环,所以如果有负权回路但是1不能到,依然是NO
后台是有这么个样例:
3 3
2 3 -1
3 4 -1
2 4 -1
存在负权回路但是1号点到不了,输出NO
所以再次遍历的时候,加个inf判断即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
int u[maxn],v[maxn],w[maxn];
int dis[maxn];
int n,m,tot;
void bellman_ford()
{
memset(dis,inf,sizeof(dis));
dis[1]=0;
for(int k=1;k<=n-1;k++)
{
for(int i=1;i<=tot;i++)
{
dis[v[i]]=min(dis[v[i]],dis[u[i]]+w[i]);
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
tot=1;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
if(c>=0)
{
u[tot]=a,v[tot]=b,w[tot]=c;
tot++;
u[tot]=b,v[tot]=a,w[tot]=c;
tot++;
}
else
{
u[tot]=a,v[tot]=b,w[tot]=c;
tot++;
}
}
tot--;
bellman_ford();
int ok=0,ok2=0;
for(int i=1;i<=tot;i++)
{
if(dis[v[i]]>dis[u[i]]+w[i]&&dis[v[i]]<inf/2)//判断1号是否能到达
{
ok=1;
break;
}
}
if(ok)
cout<<"YES"<<endl;
else
{
cout<<"NO"<<endl;
}
}
}