floyd ,dijikstra,Bellman-ford算法详解

几乎是瞬间,自己已经是大二了,真得时间过得好快,大一掠过,只有一些美好的回忆留在心头。

不扯淡了,言归正传。

图论,这名字起的太大了,其实就是一些最基本的算法,用于解决图上的最短距离的算法。

第一个是floyd 算法 很简单直白的算法,是使用邻接矩阵来求最短路的算法,其实就是通过点来松弛两点之间的距离。
例如:

for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(g[i][j]>g[i][1]+g[1][j])
 g[i][j] = g[i][1]+g[1][j];
   }
}

上面的代码就是通过编号为1的这个点来松弛每两个点,缩短他们之间的距离
所以整个核心代码就是:

for(int k=1;k<=n;k++) {  for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(g[i][j]>g[i][k]+g[k][j])
 g[i][j] = g[i][k]+g[k][j];
 }
   }
 }

之后又出现了dijikstra算法(挺难拼的)
这个算法的思路是通过边来实现松弛,它是有一个一维数组dis[] 来储存由1到各个点的距离,首先储存图中的初始距离
然后再进行处理,在这之中,是从那些估计值中选择出最小的值作为源点,因为在这算法中认为所有的边权,都是正值的,所以最小的边已经无法再通过其余的边进行松弛了,所以选其作为源点。(也正由于这思想,这个算法是无法处理带有负权边的图的)

核心代码:

while(sum<n)
        {
            int temp=maxn;
            for(int i=1;i<=n;i++)
            {
                if(book[i]==0)
                {
                    if(temp>dis[i])
                    {
                        temp = dis[i];
                        cur = i;
                    }
                }
            }
            book[cur] = 1;
            for(int i=1;i<=n;i++)
            {
                if(g[cur][i]<maxn)
                {
                    if(dis[cur]+g[cur][i]<dis[i])
                        dis[i] = dis[cur]+g[cur][i];
                }
            }
            sum++;
        }

接下来是完美的Bellman-ford算法
算法简单 又 完美的解决了负权边的问题
这个对于图的储存有了变化,它是开了三个数组
u[ ] v[ ] w[ ]
存储各个值

核心代码:

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];
            }
        }

这个算法也是通过边松弛来优化的。当运行完这个循环,在运行一次内循环,所得结果有所变化时,边说明图含有负权边。

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_32635069/article/details/52589748
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞