luogu3385 负环 (spfa)
我在做spfa的时候,如果有一个点被更新了超过N次,证明这个图里是有负环的。
(神TM输出YE5和N0)
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2020,maxm=3030; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Edge{ 16 int a,b,l,ne; 17 }eg[maxm*2]; 18 int egh[maxn],ect; 19 int N,M; 20 int cnt[maxn],dis[maxn]; 21 queue<int> q; 22 bool inq[maxn]; 23 24 inline void adeg(int a,int b,int l){ 25 eg[++ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect; 26 } 27 28 bool spfa(int s){ 29 30 while(!q.empty()) q.pop(); 31 dis[s]=0;q.push(s);cnt[s]=1; 32 while(!q.empty()){ 33 int p=q.front();inq[p]=0; 34 // printf("%d %d\n",p,dis[p]); 35 q.pop(); 36 for(int i=egh[p];i;i=eg[i].ne){ 37 int b=eg[i].b; 38 if(dis[b]>dis[p]+eg[i].l){ 39 dis[b]=dis[p]+eg[i].l; 40 if(inq[b]) continue; 41 if(++cnt[b]>N) return 1; 42 q.push(b); 43 inq[b]=1; 44 } 45 } 46 }return 0; 47 } 48 49 int main(){ 50 //freopen("","r",stdin); 51 int i,j,k; 52 for(int T=rd();T;T--){ 53 ect=0;CLR(egh,0); 54 N=rd(),M=rd(); 55 for(i=1;i<=M;i++){ 56 int a=rd(),b=rd(),c=rd(); 57 adeg(a,b,c); 58 if(c>=0) adeg(b,a,c); 59 } 60 bool ans=0; 61 CLR(cnt,0);CLR(dis,127);CLR(inq,0); 62 for(i=1;i<=N&&!ans;i++){ 63 if(!cnt[i]) ans|=spfa(i); 64 } 65 if(ans) printf("YE5\n"); 66 else printf("N0\n"); 67 } 68 return 0; 69 }