洛谷 P3385 【模板】負環 (SPFA)
阿新 • • 發佈:2020-07-26
-
題意:有一個\(n\)個點的有向圖,從\(1\)出發,問是否有負環.
-
題解:我們可以用SPFA來進行判斷,在更新邊的時候,同時更新路徑的邊數,因為假如有負環的話,SPFA這個過程一定會無限重複的遍歷這個環,那麼這個環中的邊數也就會不斷增加,因為我們只有\(n\)個點,所以假如某條路徑的邊數\(\ge n\)時,就說明有點重複使用了,也就說明一定存在負環.這題讓我們從1開始走,所以只要對1初始化一下就行了.
-
程式碼:
struct misaka{ int out; int val; }e; int t; int n,m; int dis[N]; bool st[N]; int cnt[N]; vector<misaka> v[N]; bool spfa(){ queue<int> q; st[1]=true; dis[1]=0; q.push(1); while(!q.empty()){ int node=q.front(); q.pop(); st[node]=false; for(auto w:v[node]){ int now=w.out; if(dis[now]>dis[node]+w.val){ dis[now]=dis[node]+w.val; cnt[now]=cnt[node]+1; if(cnt[now]>=n) return true; if(!st[now]){ st[now]=true; q.push(now); } } } } return false; } int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); scanf("%d",&t); while(t--){ scanf("%d %d",&n,&m); for(int i=1;i<=n;++i){ dis[i]=INF; st[i]=false; cnt[i]=0; } for(int i=1;i<=m;++i){ int a,b,val; scanf("%d %d %d",&a,&b,&val); if(val>=0){ v[a].pb({b,val}); v[b].pb({a,val}); } else v[a].pb({b,val}); } if(spfa()) puts("YES"); else puts("NO"); for(int i=1;i<=n;++i){ v[i].clear(); } } return 0; }