You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

我的Floyd Warshall算法为何出错?循环顺序影响结果的困惑

Floyd-Warshall算法实现错误分析

题目

Implementing Floyd Warshall(来自GeeksforGeeks)

我的思路

原本想让每个节点都有机会成为任意顶点对i和j的中间节点,以此计算最短路径。

错误代码

class Solution{
    public void shortest_distance(int[][] mat){
        int N = mat.length;
        
        for(int i = 0; i < N; ++i){
            for(int j = 0; j < N; ++ j){
                for(int k = 0; k < N; ++k){
                    if(mat[i][k] != -1 && mat[k][j] != -1 && (mat[i][j] == -1 || mat[i][j] > mat[i][k] + mat[k][j])){
                        mat[i][j] = mat[i][k] + mat[k][j];
                    }
                }
            }
        }
    }
}

测试用例问题

输入

12
0 4 2 1 2 9 4 8 -1 4 -1 -1
9 0 3 6 2 6 2 3 6 -1 -1 3
7 1 0 10 8 9 1 3 -1 7 -1 10
5 1 9 0 3 -1 1 10 7 1 -1 7
-1 5 1 4 0 2 10 4 10 6 4 5
7 8 3 7 5 0 5 1 3 5 7 2
6 -1 6 1 10 7 0 10 -1 -1 7 7
-1 3 2 7 4 -1 4 0 10 5 6 10
10 6 1 10 4 4 7 10 0 4 7 4
1 1 6 8 8 9 2 10 6 0 -1 3
5 9 3 -1 4 3 -1 -1 -1 3 0 1
2 2 8 6 2 4 4 3 -1 3 4 0

我的输出

0 2 2 1 2 4 2 5 7 2 6 5
5 0 3 3 2 4 2 3 6 4 6 3
6 1 0 2 3 5 1 3 7 3 7 4
2 1 4 0 3 5 1 4 7 1 7 4
6 2 1 3 0 2 2 3 5 4 4 4
4 4 3 5 4 0 4 1 3 5 6 2
3 2 5 1 4 6 0 5 8 2 7 5
6 3 2 4 4 6 3 0 9 5 6 6
5 2 1 3 4 4 2 4 0 4 7 4
1 1 3 2 3 5 2 4 6 0 7 3
3 3 3 4 3 3 4 4 6 3 0 1
2 2 3 3 2 4 4 3 7 3 4 0

预期输出

0 2 2 1 2 4 2 5 7 2 6 5
5 0 3 3 2 4 2 3 6 4 6 3
4 1 0 2 3 5 1 3 7 3 7 4
2 1 4 0 3 5 1 4 7 1 7 4
5 2 1 3 0 2 2 3 5 4 4 4
4 4 3 5 4 0 4 1 3 5 6 2
3 2 5 1 4 6 0 5 8 2 7 5
6 3 2 4 4 6 3 0 9 5 6 6
5 2 1 3 4 4 2 4 0 4 7 4
1 1 3 2 3 5 2 4 6 0 7 3
3 3 3 4 3 3 4 4 6 3 0 1
2 2 3 3 2 4 4 3 7 3 4 0

问题核心

发现把k循环移到最外层后代码就能正常运行,想不通当前循环顺序出错的原因。


问题解答

Floyd-Warshall算法的核心逻辑是逐步允许使用前k个节点作为中间节点来更新最短路径,所以k必须放在最外层循环。

你的循环顺序是i→j→k,这意味着对于每一对(i,j),你尝试用所有节点k作为中间节点更新路径,但这里的问题在于:当你更新mat[i][j]时,可能还没有计算出i到k或者k到j的最优路径——因为i和j的循环在k前面,你无法利用那些经过其他中间节点优化后的路径。

举个例子,假设存在路径i→m→k→j,当k循环到当前节点时,i→m→k的最短路径可能还没被计算出来(因为m可能在后面的i或j循环里才会被处理),导致你只能得到i→k→j的直接路径,而无法得到更短的i→m→k→j。

而正确的k→i→j顺序,是先固定中间节点集合{0,1,...,k},然后对所有i,j对,检查是否通过k作为中间节点能得到更短的路径。这样每一轮k循环后,所有经过前k个节点的最短路径都被正确更新,后续的循环可以基于这些已经优化过的路径继续计算,保证了所有可能的中间节点组合都被考虑到。

比如你测试用例中第3行第1列的结果,正确值是4,你的代码算成6——这就是因为你的循环顺序没让中间节点的优化路径被及时利用,导致没找到更短的路径。

内容的提问来源于stack exchange,提问作者Vivek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 07:35:18