Floyd-Warshall算法求任意两点间的最短路(图论算法)

算法思路简介


假设只使用顶点0~k和 i,j ,并且我们记顶点i到j的最短路径长为dp[ k + 1 ][ i ][ j ],k = -1表示只使用i,j,所以dp[ 0 ][ i ][ j ] = cost[ i ][ j ].
只使用0~k时,有经过k和不经过k两种情况,所以dp[ k + 1 ][ i ][ j ] = min( dp[ k ][ i ][ j ] , dp[ k ][ i ][ k ] + dp[ k ][ k ][ j ] )

上面的cost数组表示边的权重
dp数组的初始值是边的权重(如果存在边)

当顶点i 和 j 之间的路径不存在时,dp[ k ][ i ][ j ] = INF

这便变成了一个典型的dp,所以这个三维数组就可以直接用一个二维的代替: dp[ i ][ j ] = min( dp[ i ][ j ], dp[ i ][ k ] + dp[ k ][ j ] )


实现:

int d[MAX_V][MAX_V];
int V;
void warshall_floyd()
{
    for(int k = 0; k < V; k++)
        for(int i = 0; i < V; i++)
            for(int j = 0; j < V; j++)
                d[i][j] = min( d[i][j], d[i][k]+d[k][j] );
}

代码解析


  • 为什么最外层循环是k
    • 是为了更新dp[ i ][ j ]

      假设把k的循环放在最内层
      那么dp[ i ][ j ]就只会更新 “ 一次 ”,打个比方:
      i = 1,j = 2时,dp[ i ][ j ]会被连续更新k次,然而此时还有很多地方都没有被计算,比如k = 10时,
      dp[ 1 ][ 2 ] = min( dp[ 1 ][ 2 ], dp[ 1 ][ 10] + dp[ 10 ][ 2 ] )
      看起来没啥问题,但是呢,这时 dp[ 1 ][ 10] 和 dp[ 10 ][ 2 ]的结果都还不知道,而当计算出dp[ 1 ][ 10] 和 dp[ 10 ][ 2 ]后,dp[ 1 ][ 2 ]却不再被更新,导致无法得到正确结果


  • 时间复杂度
    • 不用多说肯定是 O( V^3 )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值