【模板】負環判定
阿新 • • 發佈:2019-03-17
算法 簡單 pre 由於 無向圖 mem -- () 等於
存在負環,即:執行 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; }
【模板】負環判定