题目链接:https://www.luogu.org/problem/P3385
bellman判负环
/*
bellman_ford判负环
洛谷3385
寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环。
从1号顶点开始的负环,(若w<0则为单向,否则双向)
存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。
1
4 3
2 3 -1
3 4 -1
4 2 -1
N0
*/
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct edge
{
int u,v,w;
}A[6010];
int n,m,t,tot;
int dis[2010];
bool bellman(int start,int m)
{
memset(dis,0x3f,sizeof(dis));
dis[start]=0;
int i;//没负环,最多跑n-1遍。
for(i=1;i<=n;i++)
{
bool flag=false;
for(int j=1;j<=m;j++)
{
if(dis[A[j].u]!=0x3f3f3f3f)//判断从start开始有负环
if(dis[A[j].v]>dis[A[j].u]+A[j].w)
{
dis[A[j].v]=dis[A[j].u]+A[j].w;
flag=true;
}
}
if(flag==false) return true;
}
return i==n+1?false:true;
}
void add(int from,int to,int w)
{
A[++tot].u=from;
A[tot].v=to;
A[tot].w=w;
}
int main()
{
int x,y,z;
for(scanf("%d",&t); t; t--)
{
tot=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
if(z>=0)add(y,x,z);
}
printf("%s\n",bellman(1,tot)==true?"N0":"YE5");
}
}