• Bellman-Ford算法


    2017-07-27  08:58:08

    writer:pprp

    参考书目:张新华的《算法竞赛宝典》

    Bellman-Ford算法是求有向图单源最短路径的,dijkstra算法的条件是图中任意一条边的权都是正的;BF算法可以解决存在负边权的图;

    算法流程分为三个部分:

    1. 初始化,将除源点外的所有顶点的最短距离的估计值D[i] = +无穷,D[sourse] = 0;
    2. 迭代求解:反复对每条边进行松弛操作,使得每个顶点的最短距离D[i]估计值主讲逼近其最短距离;运行n-1次
    3. 检验负权回路:通过松弛操作判断每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回FALSE表名问题无解;否则返TRUE,输出D[i]的值

    例题:虫洞

    代码如下:

    #include <iostream>
    
    using namespace std;
    
    int w[1001][1001],d[1001];
    int n,m;     //n 是点的个数, m是边的个数
    int change; //?
    
    void init()
    {
        cin >> n >> m;
        int x,y,v;
        for(int i = 1; i <= n ; i++)
            for(int j = 1; j <=n; j++)
                w[i][j] = INT_MAX;
        for(int i = 1; i <= m; i++)
        {
            cin >> x >> y >> v;
            w[x][y] = v;//单向通道,边的权值为v
        }
    }
    
    void bellman_ford(int x)
    {
        int i,j,k;
        for(i=1; i<=n; i++)     //initial array d
            d[i] = w[x][i];
        d[x] = 0;  //到自己距离为0
        for(k=1; k<=n-1; k++)
            for(j = 1; j >=n ; j++)   //松弛
                for(i = 1; i <=n ; i++)
                    if((w[i][j]!=INT_MAX)&&d[i]!=INT_MAX&&d[j]>d[i]+w[i][j])
                        d[j] = d[i]+w[i][j];
        change = 1;
        for(i =1; i<=n; i++)   //松弛操作判断是否存在负权回路
            for(j=1; j<=n; j++)
                if(w[i][j]!=INT_MAX&&d[i]!=INT_MAX&&d[j]>d[i]+w[i][j])
                    change = 0;
        if(change)
            cout <<"Not possoble"<<endl;
        else
            cout <<"Possible"<<endl;
    }
    
    int main()
    {
        init();
        bellman_ford(1);
        return 0;
    }
  • 相关阅读:
    ★一名“标题党”自我修炼的10大技巧
    字符编码笔记:ASCII,Unicode和UTF-8
    字符编码笔记:ASCII,Unicode和UTF-8
    字符编码笔记:ASCII,Unicode和UTF-8
    ★漫画:优秀的程序员具备哪些属性?
    ★漫画:优秀的程序员具备哪些属性?
    Linux 标准目录结构
    hadoop多次格式化后,导致datanode启动不了
    Linux天天见
    我的ipad应用备份
  • 原文地址:https://www.cnblogs.com/pprp/p/7242966.html
Copyright © 2020-2023  润新知