【模板】负环判定
存在负环,即:执行 spfa 算法时,一个点被更新了 N 次或 N 次以上,那么一定存在负环。由于无向图任意两点间的简单路径经过的边数均小于 N,且 B-F 算法在第 i 轮迭代结束时可以求得经过不超过 i 条边得到的单源最短路。因此, 在 N-1 次迭代时一定可以将所有点的最短路均求出。
更高效率的做法是记录一个点最短路经过的边数,若边数大于等于了 N,则证明出现了负环。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxv=2010;
const int maxe=3010;
inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
struct node{
int nxt,to,w;
}e[maxe<<1];
int tot=1,head[maxv];
inline void add_edge(int from,int to,int w){
e[++tot]=node{head[from],to,w},head[from]=tot;
}
int n,m,d[maxv],cnt[maxv];
bool in[maxv];
bool spfa(){
queue<int> q;
memset(d,0x3f,sizeof(d));
memset(in,0,sizeof(in));
d[1]=0,in[1]=1,q.push(1);
while(q.size()){
int u=q.front();q.pop(),in[u]=0;
if(cnt[u]>=n)return 1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(d[v]>d[u]+w){
d[v]=d[u]+w,cnt[v]=cnt[u]+1;
if(!in[v])q.push(v),in[v]=1;
}
}
}
return 0;
}
void read_and_parse(){
n=read(),m=read();
for(int i=1,x,y,z;i<=m;i++){
x=read(),y=read(),z=read();
if(z>=0)add_edge(x,y,z),add_edge(y,x,z);
else add_edge(x,y,z);
}
}
void solve(){
puts(spfa()?"YE5":"N0");
}
void init(){memset(head,0,sizeof(head)),memset(cnt,0,sizeof(cnt)),tot=1;}
int main(){
int T=read();
while(T--){
init();
read_and_parse();
solve();
}
return 0;
}