王道论坛机考系列——图论之最短距离

王道论坛机考系列——图论之最短距离

最短距离——Floyd算法(解决全源)

寻找图中某两个特定节点之间的最短路径的长度。
图使用邻接矩阵edge[i][j]表示,edge[i][j]最初始的时候表示的是从节点i不经过任何节点到节点j的距离,如果不存在则设置为无穷大。那么从节点i开始可以经过节点l再到节点j,此时需要比较edge[i][l]+edge[l]][j]与edge[i][j]的大小,如果前者比较小,那么edge[i][j]的值需要更换一下(其中edge[i][l]表示从i到l不经过任何节点的距离,edge[l][j]表示从l到j不经过任何中间节点的距离),换做更一般的情况,当从i到j的中间节点数量增多时,可以使用ans[k][i][j]表示从节点i开始只经过小于等于k的节点到达j节点时的最短路径。计算的过程只需要从k等于1到n计算图中所有节点i到节点j之间的距离, ans[0][i][j]表示从i到j的直接距离。

使`cpp描述短发可以表示如下所示:

for (int k = 1; k <= n; k++) {
   
    //  计算只经过小于等于k的节点到达j节点时的最短路径
    for (int i = 1; i <= n; i++) {
   
        for (int j = 1; j <= n; j++) {
   
            //  遍历所有的i,j
            if (ans[k-1][i][k] == INT_MAX || ans[k-1][k][j] == INT_MAX) {
   
                //  表示经过前k-1个节点时,i或者j不与k相通
                ans[k][i][j] = ans[k-1][i][j];
                // 保持原值,即从i到j经过k个节点和经过k-1个节点最终得到的结果是一样的
                continue;  //继续执行程序
            }

            if (ans[k-1][i][j] == INT_MAX ||
                ans[k-1][i][k] + ans[k-1][k][j] < ans[k-1][i][j])
                ans[k][i][j] = ans[k-1][i][k] + ans[k-1][k][j];
            else
                ans[k][i][j] = ans[k-1][i][j];
        }
    }
}

上面的方法中使用ans[k-1][i][j]的值来推导得到ans[k][i][j]的值时,值得注意的是ans[k][i][k] 和 ans[k][k][j]的值与 ans[k-1][i][k]和 ans[k-1][k][j]的值相同。所以程序更新为以下的内容,程序的运行结果与上面的运行结果是一样的,成功的将需要使用三位数组来解决的问题变成了只需要使用二维数组就可以解决的问题:

for (int k = 1; k <= n; k++) {
   
    for (int i = 1; i <= n; i++) {
   
        for (int j = 1; j <= n; j++) {
   
            if(ans[i][k] == INT_MAX || ans[k][j] == INT_MAX)
                continue;
            if (ans[i][j] == INT_MAX || ans[i][k] + ans[k][j] < ans[i][j])
                    ans[i][j] 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值