zoukankan      html  css  js  c++  java
  • Bellman-Bord(贝尔曼-福特)

    include<stdio.h>

    const int inf=0x3f3f3f3f;
    int main()
    {
    int m,n;
    scanf("%d%d",&n,&m);
    int u[n+1],v[n+1],w[n+1];
    for(int i=1; i<=m; i++)
    scanf("%d%d%d",&u[i],&v[i],&w[i]);
    int dis[n+1];
    for(int i=1; i<=n; i++)
    dis[i]=inf;
    dis[1]=0;
    for(int k=1; k<=n-1; k++)
    {

        for(int i=1; i<=m; i++)
            if(dis[v[i]]>dis[u[i]]+w[i])
                dis[v[i]]=dis[u[i]]+w[i];
     
    }
    int check=0;
    for(int i=1;i<=m;i++)
        if(dis[v[i]]>dis[u[i]]+w[i])check=1;//进行第n次松弛
    if(check==1)printf("有回路");
    else
    {
        for(int i=1;i<=n;i++)
            printf("%d
    ",dis[i]);
    }
    return 0;
    

    }

    图解

    A是源点
    1: 初始化 A到所有的点都是 无穷大 dao自身的距离为0;
    2: 开始遍历第一条边 A--->D 即以A作为中转站 A---->A--->D A到A的距离为0 A到D的距离为3 所以A到D的距离从无穷大变为3
    3: 遍历第二条边 B----->C 以B作为中转站 A---->B---->C 此时A到B的距离为无穷大 B到C的距离为6 所以A到C的距离为无穷大 松弛失败
    4: 遍历第三条边 A---->B 以A作为中转站 A---->A--->B A到A的距离为0 A到B的距离为2 所以A到B的距离从无穷大变为2
    5: 遍历第四条边B----->D 以B作为中转站 A---->B---->D A到B的距离为2 B到D的距离为5 但是又第二步已经计算出D到源点的距离为3且
    小于5+2 即A到D的距离不变还是原来的3
    6: 遍历第五条边 C---->F 以C作为中专站 A---->C---->F A到C的距离为无穷大 C到F的距离为7 所以A到F的距离为无穷大 即松弛失败
    7:遍历第六条边 D---->E 以D作为中专站 A---->D---->E A到D的距离为3 D到E的距离为8 所以A到E的距离为8+3=11

    经过一轮松弛之后发现还存在点到源点的距离是无穷大的 显然不合理
    因为在执行第三步时 由于B到A的距离为无穷大 所以不能经B中转使得C到A的距离变短 但是 在执行第四步时 B到A的距离就已经变为2了
    明显可以用B来作为中转站使得C到A的距离变短 由此可见 还需进行一轮松弛

    那么之多进行多少轮松弛呢 应该是n-1(顶点的个数减一,这是最坏的情况 即是每轮只松弛了一条边)
    如果进行第n松弛仍可以是最短路发生变化,说明此图中存在负全回路

    当然这种可能性不大 大多数情况下松弛不到n-1轮就已经是最短了 再继续进行松弛时也不会发生变化

    所以可以优化 (SPFA)

    梦里不知身是客,一晌贪欢。
  • 相关阅读:
    [转载]深入理解JavaScript闭包(closure)
    CSS Sprite初探之原理、使用
    动软,我被你迷惑了
    win7系统下CamtasiaStudio无法录上电脑声音只能录麦克风声音的解决办法
    [转载]向高级Javascript程序员阵营迈进:Javascript一些概念研究总结
    [转载]最简单的.NET生成随机数
    [转载]完全理解关键字this
    [转载]什么是高内聚、低耦合
    [转载]CSS背景:css background属性全解析
    [转载]HTML5语音输入(淘宝语音搜索)方法
  • 原文地址:https://www.cnblogs.com/dccmmtop/p/5479421.html
Copyright © 2011-2022 走看看