zoukankan      html  css  js  c++  java
  • 图论-Bellman-Ford算法

    大致的算法:

    struct Node{
        int v,dis;
    };
    vector<Node>Adj[MAXV];
    int n,d[MAXV];
    bool Bellman(int s)
    {
        fill(b,b+MAXV,INF);
        d[s]=0;
        for(int i=0;i<n-1;i++)
        {
            for(int u=0;u<n;u++)
            {
                for(int j=0;j<Adj[u].size();j++)
                {
                    int v=Adj[u][j].v , dis = Adj[u][j].dis;
                    if(d[u]+dis<d[v])
                    {
                        d[v]=d[u]+dis;    //松弛操作 
                    } 
                }
            }
        }
        //判断是否有负环的代码 
        for(int u=0;u<n;u++)
        {
            for(int j=0;j<Adj[u].size();j++)
            {
                int v=Adj[u][j].v , dis = Adj[u][j].dis;
                if(d[u]+dis<d[v])
                {
                    //d[v]=d[u]+dis;松弛操作
                    return false; 
                } 
            }
        }
        return true;
    }

    实例:一般正常的没有源点可达的负环

    因此判断负环的过程可以省略。

    #include<cstdio>
    #include<vector>
    #include<set>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXV = 1000;
    const int INF = 0xFFFFFFF;
    struct Node{
        int v,dis;;
        Node(int _v,int _dis){ v=_v ; dis=_dis; }
    };
    vector<Node>Adj[MAXV];
    int n,m,st,ed,weight[MAXV];
    int d[MAXV],w[MAXV],num[MAXV];
    set<int>pre[MAXV];
    //使用邻接表实现,因为邻接矩阵的复杂度达到O(V^3),而邻接表只有O(VE) 
    bool Bellman(int s)
    {
        fill(d,d+MAXV,INF);
        memset(w,0,sizeof(w));
        memset(num,0,sizeof(num));
        d[s]=0;
        w[s]=weight[s];
        num[s]=1;
        for(int i=0;i<n-1;i++) //n-1操作 
        {
            for(int u=0;u<n;u++)
            {
                for(int j=0;j<Adj[u].size();j++)
                {
                    int v=Adj[u][j].v;
                    int dis=Adj[u][j].dis;
                    if(d[u]+dis<d[v])
                    {
                        d[v]=d[u]+dis;
                        num[v]=num[u];
                        w[v]=w[u]+weight[v];
                        pre[v].clear();
                        pre[v].insert(u);    
                    }
                    else if(d[u]+dis==d[v])
                    {
                        if(w[u]+weight[v]>w[v])
                        {
                            w[v]=w[u]+weight[v];
                        }
                        pre[v].insert(u);
                        num[v]=0;
                        set<int>::iterator it;
                        for(it=pre[v].begin();it!=pre[v].end();it++) num[v]+=num[*it];
                    }    
                }    
            }    
        } 
        /*
        省略了判断是否存在负环的操作
        for(int u=0;u<n;u++)
        {
            for(int j=0;j<Adj[u].size();j++)
            {
                int v=Adj[u][j].v;
                int dis=Adj[u][j].dis;
                if(d[u]+dis<d[v])
                {
                    return false;
                }                
            }    
        }    
        */
        return true; 
    }
    int main(void)
    {
        scanf("%d%d%d%d",&n,&m,&st,&ed);
        for(int i=0;i<n;i++) scanf("%d",&weight[i]);
        int u,v,wt;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&wt);
            Adj[u].push_back(Node(v,wt));
            Adj[v].push_back(Node(u,wt)); 
        }
        Bellman(st);
        printf("%d %d
    ",num[ed],w[ed]);
        return 0;    
    } 
  • 相关阅读:
    final详解
    静态与非静态
    静态内部类详解
    iso-----genisoimage/md5sum命令用法
    Docker-----版本选择
    Docker-----deepin系统下docker安装registry
    shell高级-----正则表达式
    kolla-ansible-----rally模块
    shell高级-----创建函数
    jenkins入门-----(1)安装、配置
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8847086.html
Copyright © 2011-2022 走看看