zoukankan      html  css  js  c++  java
  • HDU-2544-最短路(Bellman-Ford)

    Bellman-Ford算法是一个时间复杂度很高,但是它可以用来判断负环
    在这里插入图片描述
    负环就是上面的图,那个环的整体值小于零了,所以就是负环。
    我们用Bellman-Ford算法进行更新,打一个表出来:
    k a b c s
    0
    0 1
    0 1 -2 2
    0 1 -2 -1 2
    0 0 -2 -1 1

    这时候,我们已经跑完更新的块了,然后我们运行检查的块,当我们检查到B点的时候,发现d[A]+AB<d[B],所以d[B]就一直在减小,所以上面的更新是无效的。
    因为我们跑更新的时候最多跑n-1步就可以了,n是顶点数,所以我们再次更新,不可能更新出新的结果来,所以就含有负环,所以直接return。
    这题是个板子题,写个Bellman-Ford试试手,其中注释掉的代码块也是可以用的。

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n, m, s, e, t;  
    int d[110];
    
    struct Edge {
        int from, to, cost;
    }es[10005];
    
    // void Bellman_Ford()
    // {
    //     memset(d, INF, sizeof(d));
    //     d[1] = 0;
    //     while (true) {
    //         bool update=false;
    //         for (int j = 1; j <= m;j++) {
    //             Edge e = es[j];
    //             if (d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost) {
    //                 d[e.to] = d[e.from] + e.cost;
    //                 update = true;
    //             }
    //             if (d[e.to]!=INF&&d[e.from]>d[e.to]+e.cost) {
    //                 d[e.from] = d[e.to] + e.cost;
    //                 update = true;
    //             }
    //         }
    //         if (!update)
    //             break;
    //     }
    // }
    
    void Bellman_Ford()
    {
        memset(d, INF, sizeof(d));
        d[1] = 0;
        for (int i = 1; i < n;i++) {
            for (int j = 1; j <= m;j++) {
                Edge e = es[j];
                if (d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost) {
                    d[e.to] = d[e.from] + e.cost;
                }
                if (d[e.to]!=INF&&d[e.from]>d[e.to]+e.cost) {
                    d[e.from] = d[e.to] + e.cost;
                }
            }
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        while (cin>>n>>m&&n+m) {
            for (int i = 1; i <= m;i++) {
                cin >> es[i].from >> es[i].to >> es[i].cost;
            }
            Bellman_Ford();
            cout << d[n] << endl;
        }
    }
    
    
  • 相关阅读:
    《UNIX环境高级编程》笔记--UNIX标准化及实现
    SPOJ1811最长公共子串问题(后缀自动机)
    一个leetcode解题报告类目,代码很简洁
    字符压缩题目
    求最佳会议地点
    实现树的横向指针
    lower_bound与upper_bound
    求到所有房子距离和最小的新房子
    增加限制条件的矩阵求和
    切分数组来得到一定的和
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10350135.html
Copyright © 2011-2022 走看看