Floyd 算法 求最短路

推荐阅读:最短路 - OI Wiki
练习题目:力扣 - 1334

简介:

  • 初始化:我们先把题目给的,两点直接相连的边的加入初始存在连接中。
  • 更新:然后每次只加入一个点对已有合法连接进行“拓展”更多的连接。
  • 结果:那么所有点加入后,即为整个图的连接状况。

定义一个数组 f[ k ][ a ][ b ],表示只允许经过结点 1 到 k,结点 a 到结点 a 的最短路长度。

f[ 0 ][ a ][ b ] 就是不经过任何点时,点 a 与点 b 之间的距离。题目给的所有两点的连接都存入。其余都初始化为无穷大(如:0x3f3f3f3f)

更新举例:
f[ 1 ][ a ][ b ] = min( f[ 1 ][ a ][ b ] , f[ 0 ][ a ][ 1 ] + f[ 0 ][ 1 ][ b ] );
对当前连接(k == 1)取最小值,而 k == 0我们刚才所有的都初始化好了。

板子:

//### 初始化 #####################################
//直接相连的边加入
//以及自己和自己
		for(auto& arr:edges){
            f[arr[0]+1][arr[1]+1] = min(arr[2],f[arr[0]+1][arr[1]+1]);//应对多条重边
            f[arr[1]+1][arr[0]+1] = min(arr[2],f[arr[1]+1][arr[0]+1]);
        }
        for(int a=1;a<=n;a++){
            f[a][a] = 0;
        }
        
//*** 动态规划来更新 ******************************
        for(int i=1;i<=n;i++){
            for(int a=1;a<=n;a++){
                for(int b=1;b<=n;b++){
                    f[i][a][b] = min(f[i-1][a][b],f[i-1][a][i]+f[i-1][i][b]);
                }
            }
        }

内存优化:

for(int i=1;i<=n;i++){
            for(int a=1;a<=n;a++){
                for(int b=1;b<=n;b++){
                    f[a][b] = min(f[a][b],f[a][i]+f[i][b]);
                }
            }
        }

证明:

在这里插入图片描述


核心就是:对于每个f[i][a][b]要的都是【 i 列最小 + i 行最小 】,而“在原地进行更改也不会改变最小值的值”。因为你永驻这一行这一列。而且是求和啊,肯定比这一行这一列的最小值要大的。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值