Floyd算法

Floyd算法

  本文主要讲解的是Floyd算法,这同样是经典的最短路算法之一。不同的是,如果要求出一个图上任意两点间的最短路径,我们无需调用n次Dijkstra算法,这时Floyd算法便有了用武之地。另外,该算法同样适用于存在负权的情况。
  Floyd算法本质上是动态规划,核心是动态转移方程,重点在于分析与推导。下面我们就来分析问题。从点i到点j的最短路径不外乎有两种可能:第一种是直接从i到j;第二种是从点i经过若干个结点再到点j。因此,我们对于每个结点k,检查是否有d(i, k)+d(k, j) < <script type="math/tex" id="MathJax-Element-7"><</script>d(i, j)成立,若成立则更新d(i, j)=d(i, k)+d(k, j) (即边的松弛操作)。这样,当我们遍历完所有的结点k时,得到的d(i, j)即为从点i到点j的最短距离。
  不难写出状态转移方程:d[i][j] = min(d[i][j], d[i][k] + d[k][j]),用三重循环即可轻松地写出代码。给出核心代码如下:

for(int k = 0; k < n; k++)
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            if(d[i][j] < INF && d[k][j] < INF)
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

  调用上述代码之前,只需做一点简单的初始化:d[i][i]=0,其他d值均为正无穷。很显然,Floyd算法的时间复杂度为O(n^3)。它可以方便地求出图中任意两点的最短路,尤其是对于稠密图的效果更佳。但是,由于很高的时间复杂度,在n较大时不适合使用。
  此外,我们在实际应用中,有时并不关心路径的长度,而是只关心每两点间是否存在通路。用true和false表示是否连通,则我们需要调整一下初始化,并把“d[i][j] = min(d[i][j], d[i][k] + d[k][j])”改为“d[i][j] = d[i][j] || (d[i][k] && d[k][j])”。这样得出的结果称为传递闭包(Transitive Closure)。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值