负环判断模版

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 }
View Code

 

posted @ 2017-10-03 22:50  white_hat_hacker  阅读(147)  评论(0编辑  收藏  举报