• 最短路之Bellman-Ford算法


    Bellman-Ford算法通过对边进行松弛操作来渐进地降低从源结点到其他结点的最短路径
    每次循环:对所有的边进行松弛操作
    循环次数:共循环n-1次(n为顶点数)
    故时间复杂度: O(VE)

    /* Bellman-Ford算法 --- 以边为存储结构 */
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <cstring>
    using namespace std;
    
    const int maxn = 100;
    const int INF = 65535;
    
    struct Edge{
        int from, to, dist;
        Edge(){}
        Edge(int a, int b, int c) :from(a), to(b), dist(c){}
    };
    
    vector<int> G[maxn]; //G[i]-->以i为起点的边
    vector<Edge> edges;  //
    int inq[maxn], cnt[maxn];
    int d[maxn], pre[maxn];
    bool visit[maxn];
    int n, m;
    
    /************************************************************************
      Bellman-Ford算法通过对边进行松弛操作来渐进地降低从源结点到其他结点的最短路径
      每次循环:对所有的边进行松弛操作
      循环次数:共循环n-1次(n为顶点数)
      故时间复杂度: O(VE)
     ************************************************************************/
    bool bellman_ford2(int v0){
        for (int i = 0; i < n; ++i)
            d[i] = INF;
        d[v0] = 0;
        for (int i = 0; i < n; ++i){
            //对所有的边进行松弛
            for (int j = 0; j < edges.size(); ++j){
                int x = edges[j].from;
                int y = edges[j].to;
                int w = edges[j].dist;
                if (d[x] + w < d[y]){
                    d[y] = d[x] + w;
                    pre[y] = x;
                }
            }
        }
        /* 判断是否存在负环 */
        for (int j = 0; j < edges.size(); ++j){
            Edge tmp = edges[j];
            if (d[tmp.from] + tmp.dist < d[tmp.to])
                return false;
        }
        return true;
    }
    
    /* 利用队列代替循环实现 */
    bool bellman_ford(int s){
        queue<int> Q;  //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;
                    pre[e.to] = u; 
                    if (!inq[e.to]){
                        Q.push(e.to);
                        inq[e.to] = true;
                        //若对结点的访问次数大于n则存在负环
                        if (++cnt[e.to] > n){
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
    
    
    int main()
    {
        int u, v, w, k;
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; ++i){
            scanf("%d%d%d", &u, &v, &w);
            edges.push_back(Edge(u, v, w));
            k = edges.size();
            G[u].push_back(k - 1);
            //有向图可需要再加上这3行
            //edges.push_back(Edge(v, u, w));
            //k = edges.size();
            //G[v].push_back(k - 1);
        }
        if(bellman_ford(0)){
            for (int i = 0; i < n; ++i){
                printf("%d  ", d[i]);
            }
        }
        printf("
    ");
        //0-1的路径的反序
        k = 1;
        while (k != 0){
            printf("%3d ", k);
            k = pre[k];
        }
        printf("%3d
    ", k);
    
        ////以边为存储结构的输出
        //while (k != 0){
        //    printf("%3d", k);
        //    k = edges[pre[k]].from;
        //}
        //printf("%3d
    ", k);
        
        return 0;
    }
    
    /*
    
    带负权的图
    5 10
    0 1 6
    0 3 7
    1 2 5
    1 3 8
    1 4 -4
    2 1 -2
    3 2 -3
    3 4 9
    4 0 2
    4 2 7
    
    0到其他点的最短路(带负环则结束)
        dis ---> 0 2 4 7 -2
    
    */
    View Code
  • 相关阅读:
    PowerShell2.0之Windows排错(二)查看服务依存性
    PowerShell2.0之桌面计算机维护(八)关闭或重启远程计算机
    PowerShell2.0之桌面计算机维护(九)磁盘管理
    PowerShell2.0之桌面计算机维护(五)管理桌面电源设置
    PowerShell2.0之桌面计算机维护(四)审核安全的屏幕保护程序
    PowerShell2.0之桌面计算机维护(七)性能计数器
    PowerShell2.0之Windows排错(三) 检查设备驱动
    Nacos服务分级存储模型、集群、负载均衡
    Nacos安装
    Nacos注册中心之搭建工程
  • 原文地址:https://www.cnblogs.com/tommychok/p/5049817.html
Copyright © 2020-2023  润新知