• Bellman-Ford


    转自:https://www.cnblogs.com/TreeDream/p/6123476.html

    第一个Bellman-Ford算法是紫书上的;

    解析:

    1、起点入队列

    2、初始化点到起点的距离是INF;

    3、和Dijkstra相比,每个结点可以多次加入(如果有负环,那么这个结点是可以多次松弛的,一旦次数无穷就说明了这的确是个负环);

    4、因为是从起点出发的,然后在搜索邻接表,没有找到负环,只能说明,从起点到不了负环,但是可能是有负环的。没有负环,最短路数组 d 是正确可用的。

    第二个Bellman-Ford算法是白书上的;

    解析:

    1、Bellman-Ford 算法一个重要应用就是判负环,上面的一个起点入队列,就要改成所有点入队列。

    2、初始化 d 数组为 0:

      可以从第二图中,有一个负环,但是从 0 ,无法松弛;但是,在队列中,从 1 开始搜索的时候,还是可以松弛,并且找到这个负环;然后由于每个结点之前都入过队列,就能保证找到那个负环。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int maxn = 1000;
    
    struct Edge
    {
        int from,to;
        int dist;
    };
    
    struct BellmanFord
    {
        int n,m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        int d[maxn];
        int p[maxn];
        int cnt[maxn];
    
        void init(int n)
        {
            this->n = n;
            for(int i=0; i<n; i++) G[i].clear();
            edges.clear();
        }
    
        void AddEdge(int from,int to,int dist)
        {
            edges.push_back((Edge)
            {
                from,to,dist
            });
            m = edges.size();
            G[from].push_back(m-1);
        }
    
        bool negativeCycle(int s)
        {
            queue<int> Q;
            memset(inq,0,sizeof(inq));
            memset(cnt,0,sizeof(cnt));
    
            for(int i=0; i<n; i++)
            {
                d[i] = INF;
            }
    
            d[s] = 0;
            inq[s] = true;
            Q.push(s);
    
            while(!Q.empty())
            {
                int u = Q.front();
                Q.pop();
                inq[u] = false;
                for(int i=0; i<G[u].size(); i++)
                {
                    Edge& e = edges[G[u][i]];
                    if(d[u]<INF&&d[e.to]>d[u]+e.dist)
                    {
                        d[e.to] = d[u] + e.dist;
                        p[e.to] = G[u][i];
                        if(!inq[e.to])
                        {
                            Q.push(e.to);
                            inq[e.to] = true;
                            if(++cnt[e.to]>n)
                                return false;
                        }
                    }
                }
            }
            return true;
        }
    
    };
    
    struct BellmanFord
    {
        int n,m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        int d[maxn];
        int p[maxn];
        int cnt[maxn];
    
        void init(int n)
        {
            this->n = n;
            for(int i=0; i<n; i++) G[i].clear();
            edges.clear();
        }
    
        void AddEdge(int from,int to,int dist)
        {
            edges.push_back((Edge)
            {
                from,to,dist
            });
            m = edges.size();
            G[from].push_back(m-1);
        }
    
        bool negativeCycle()
        {
            queue<int> Q;
            memset(inq,0,sizeof(inq));
            memset(cnt,0,sizeof(cnt));
            for(int i=0; i<n; i++)
            {
                d[i] = 0;
                inq[0] = true;
                Q.push(i);
            }
    
            while(!Q.empty())
            {
                int u = Q.front();
                Q.pop();
                inq[u] = false;
                for(int i=0; i<G[u].size(); i++)
                {
                    Edge& e = edges[G[u][i]];
                    if(d[e.to]>d[u]+e.dist)
                    {
                        d[e.to] = d[u] + e.dist;
                        p[e.to] = G[u][i];
                        if(!inq[e.to]) {
                            Q.push(e.to);
                            inq[e.to] = true;
                            if(++cnt[e.to]>n)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
    
    };
    View Code
  • 相关阅读:
    hdu 1151
    DAG的最小路径覆盖和二分图的最大匹配
    二部图 最小点覆盖集与最大匹配的关系
    sdut 2151
    sdut Emergency
    作业
    Node.prototype.contains
    微博登录
    markdown
    Object.observe
  • 原文地址:https://www.cnblogs.com/kayiko/p/12330928.html
Copyright © 2020-2023  润新知