AcWing904 虫洞(spfa判负环)
技巧,将所有点距离置为0,并加入队列。
当某个最短路大于等于n,根据容斥原理得负环
#include<bits/stdc++.h> using namespace std; const int N=510,M=52100; int h[M],ne[M],e[M],w[M],idx; int n,m1,m2; int dis[N],st[N]; int cnt[N]; void add(int a,int b,int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } bool spfa(){ memset(dis,0,sizeof dis); memset(cnt,0,sizeof cnt); memset(st,0,sizeof st); int i; queue<int> q; for(i=1;i<=n;i++){ q.push(i); st[i]=1; } while(q.size()){ int t=q.front(); q.pop(); st[t]=0; for(i=h[t];i!=-1;i=ne[i]){ int j=e[i]; if(dis[j]>dis[t]+w[i]){ dis[j]=dis[t]+w[i]; cnt[j]=cnt[t]+1; if(cnt[j]>=n) return true; if(!st[j]) q.push(j); } } } return false; } int main(){ int t; cin>>t; while(t--){ cin>>n>>m1>>m2; int i; memset(h,-1,sizeof h); for(i=1;i<=m1;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } for(i=1;i<=m2;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,-c); } if(spfa()) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
没有人不辛苦,只有人不喊疼