图算法--判负环

bellman-ford判负环,据bellman-ford的性质最后得出的是通过不超过n-1条边的从起点到其他点的最短距离(因为n个点,所以n-1条边)

但是如果在n-1次循环之后仍然存在边可以被松弛,那么就存在负环(因为如果没有负环n-1次就已经确定了最短距离,具体可参考bellman-ford证明,已经是最短距离了还能被松弛,必然是存在负环)

 1 #include<iostream>
 2 using namespace std;
 3 const int N=2010,M=1e5+10;
 4 int n,m;
 5 struct edge{
 6     int a,b,w;
 7 }edges[M];
 8 int dis[N];
 9 void bellman_ford(){
10     //直接把dis初始化为全0就可以了,意思就是所有的点都是起点
11     for(int i=0;i<n-1;i++){
12         for(int j=0;j<m;j++){
13             auto t=edges[j];
14             if(dis[t.b]>dis[t.a]+t.w){
15                 dis[t.b]=dis[t.a]+t.w;
16             }
17         }
18     }
19 }
20 int main(void){
21     cin>>n>>m;
22     for(int i=0;i<m;i++){
23         int a,b,c;
24         cin>>a>>b>>c;
25         edges[i]={a,b,c};
26     }
27     bellman_ford();
28     for(int j=0;j<m;j++){
29             auto t=edges[j];
30             if(dis[t.b]>dis[t.a]+t.w){
31                 cout<<"Yes";
32                 return 0;
33             }
34     }
35     cout<<"No";
36     return 0;
37 }

spfa判负环

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=2010,M=1e5+10;
 6 int n,m;
 7 int h[N],e[M],w[M],ne[M],idx;
 8 int dis[N],cnt[N];
 9 bool st[N];
10 void add(int a,int b,int c){
11     e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
12 }
13 bool spfa(){
14     queue<int> q;
15     for(int i=1;i<=n;i++){
16         q.push(i);
17         st[i]=true;
18     }//把所有的点都丢进队列里面
19     while(q.size()){
20         int t=q.front();
21         q.pop();
22         st[t]=false;
23         for(int i=h[t];i!=-1;i=ne[i]){
24             int j=e[i];
25             if(dis[j]>dis[t]+w[i]){
26                 dis[j]=dis[t]+w[i];
27                 cnt[j]=cnt[t]+1;
28                 if(cnt[j]>=n){
29                     return true;
30                 }
31                 if(!st[j]){
32                     q.push(j);
33                     st[j]=true;
34                 }
35             }
36         }
37     }
38     return false;
39 }
40 int main(void){
41     cin>>n>>m;
42     memset(h,-1,sizeof(h));
43     for(int i=0;i<m;i++){
44         int a,b,c;
45         cin>>a>>b>>c;
46         add(a,b,c);
47     }
48     if(spfa()){
49         cout<<"Yes";
50     }else{
51         cout<<"No";
52     }
53     return 0;
54 }

 

posted on 2020-11-19 14:13  greenofyu  阅读(191)  评论(0编辑  收藏  举报