zoukankan      html  css  js  c++  java
  • 图算法--判负环

    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 }
  • 相关阅读:
    变量按数据类型分类
    构造方法重载 及注意事项
    构造方法-带参
    构造方法-无参
    对对象中的属性赋值(两种方法)
    局部变量的值赋给成员变量 案例(红色字体)
    成员变量与局部变量区别
    创建对象综合案例
    20151015css3 部分css2的内容
    20151012jq4
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14005305.html
Copyright © 2011-2022 走看看