负环判断模版
1,当图中不存在重边或自环时,可以用普通的dfs搜索,当存在时,普通的dfs便无能为力了,需要使用SPFA算法
2,初始时所有的d全部赋成0,可以很大幅度上提升效率,这是和最短路不同的地方
3,每个点都要搜索,当每个点都找不到负环时,才可以认为没有负环
例题:https://www.luogu.org/problem/show?pid=U13273
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #define MAXN 505 6 #define MAXM 3005 7 using namespace std; 8 int read(){ 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();} 11 while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 int first[MAXN],Next[MAXM*2],to[MAXM*2],Val[MAXM*2],cnt; 15 //double edge 16 int d[MAXN],b[MAXN]; 17 int n,m,p; 18 void Add(int x,int y,int w){ 19 Next[++cnt]=first[x];first[x]=cnt;to[cnt]=y;Val[cnt]=w; 20 } 21 int SPFA(int x){ 22 //!!! 23 if(b[x]){ 24 return 1; 25 } 26 b[x]=1; 27 for(int e=first[x];e;e=Next[e]){ 28 int y=to[e],w=Val[e]; 29 if(d[y]>d[x]+w){ 30 d[y]=d[x]+w; 31 if(SPFA(y)){ 32 return 1; 33 } 34 } 35 } 36 b[x]=0; 37 return 0; 38 } 39 void solve(){ 40 memset(first,0,sizeof(first)); 41 memset(Next,0,sizeof(Next)); 42 memset(to,0,sizeof(to)); 43 memset(Val,0,sizeof(Val)); 44 memset(d,0,sizeof(d)); 45 memset(b,0,sizeof(b)); 46 cnt=0; 47 n=read();m=read();p=read(); 48 for(int i=1;i<=m;i++){ 49 int x,y,w; 50 x=read();y=read();w=read(); 51 Add(x,y,w); 52 Add(y,x,w); 53 } 54 for(int i=1;i<=p;i++){ 55 int x,y,w; 56 x=read();y=read();w=read(); 57 Add(x,y,-w); 58 } 59 for(int i=1;i<=n;i++){ 60 if(SPFA(i)){ 61 printf("YES\n"); 62 return ; 63 } 64 } 65 printf("NO\n"); 66 } 67 int main() 68 { 69 int T; 70 T=read(); 71 for(int i=1;i<=T;i++){ 72 solve(); 73 } 74 return 0; 75 }