1. 程式人生 > >負環判斷模版

負環判斷模版

class 全部 不同 main a算法 spfa 算法 efi str

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

負環判斷模版