luogu3385 负环 (spfa)

时间:2021-10-31 15:32:04

我在做spfa的时候,如果有一个点被更新了超过N次,证明这个图里是有负环的。

(神TM输出YE5和N0

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=,maxm=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int a,b,l,ne;
}eg[maxm*];
int egh[maxn],ect;
int N,M;
int cnt[maxn],dis[maxn];
queue<int> q;
bool inq[maxn]; inline void adeg(int a,int b,int l){
eg[++ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect;
} bool spfa(int s){ while(!q.empty()) q.pop();
dis[s]=;q.push(s);cnt[s]=;
while(!q.empty()){
int p=q.front();inq[p]=;
// printf("%d %d\n",p,dis[p]);
q.pop();
for(int i=egh[p];i;i=eg[i].ne){
int b=eg[i].b;
if(dis[b]>dis[p]+eg[i].l){
dis[b]=dis[p]+eg[i].l;
if(inq[b]) continue;
if(++cnt[b]>N) return ;
q.push(b);
inq[b]=;
}
}
}return ;
} int main(){
//freopen("","r",stdin);
int i,j,k;
for(int T=rd();T;T--){
ect=;CLR(egh,);
N=rd(),M=rd();
for(i=;i<=M;i++){
int a=rd(),b=rd(),c=rd();
adeg(a,b,c);
if(c>=) adeg(b,a,c);
}
bool ans=;
CLR(cnt,);CLR(dis,);CLR(inq,);
for(i=;i<=N&&!ans;i++){
if(!cnt[i]) ans|=spfa(i);
}
if(ans) printf("YE5\n");
else printf("N0\n");
}
return ;
}