如果一个图中有负环,用SPFA算法将会陷入死循环,因为到每一点的最小值都会一直减少,所以会一直更新,结点便会一直入队。
因此判断入队次数是否大于n即可判断是否有负环
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t,n,m,u,v,w,cnt,head[100005],dis[100005],tot[100005];
struct node{
int to,w,next;
}edge[100005];
void add_edge(int from,int to,int w){
edge[++cnt].to=to;
edge[cnt].w=w;
edge[cnt].next=head[from];
head[from]=cnt;
}
int main(){
ios::sync_with_stdio(0);
cin>>t;
while(t--){
bool f=0;
cin>>n>>m;
memset(edge,0,sizeof(edge));
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
add_edge(u,v,w);
if(w>=0)add_edge(v,u,w);
}
memset(dis,0x3f,sizeof(dis));
memset(tot,0,sizeof(tot));
queue<int> q;
q.push(1);dis[1]=0;tot[1]=1;
while(!q.empty()){
int t=q.front();q.pop();
if(++tot[t]>n){
f=1;
break;
}
for(int i=head[t];i;i=edge[i].next){
int to=edge[i].to,w=edge[i].w;
if(dis[to]>dis[t]+w){
dis[to]=dis[t]+w;
q.push(to);
}
}
}
if(f)cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}