直入主题,对于Floyd的算法代码描述如下:
for (int k=0; k<n; ++k)
for (int i=0; i<n; ++i)
for (int j=0; j<n; ++j)
if (dp[i][k] + dp[k][j] < dp[i][j] )
dp[i][j] = dp[i][k] + dp[k][j];
首先要明确一个事实,对于任意i,j,要求 d p [ i ] [ j ] dp[i][j] dp[i][j]的最小值,我们一定能保证该最短路径最多经过n-1条边,也就是说从i到j的路径有多条,每条路径可能包含1~n-1条边,记i,j的最短路径经过了k条边(1<=k<n),对于该最短路径上的点,其最短路径经过的边一定小于k,否则与i,j的最短路径产生矛盾。
进一步,我们会想,如果要计算i,j的最短路径需要多少次迭代(就是外层循环的次数)呢?答案是k次。
我们想,对于i,j之间的点,我们不妨给其一个标号,假设i的编号为0,依次编号直到j为j-i,经过m次迭代,我们可以得到编号为m到i的最短路径,因此,要得到编号为j到i的最短路径,需要k次。
因此,Floyd的有效性也显示了,对于任意两个点之间,其最短路径经过的边数最多为n-1条(即使是环状也不会超过n条),因此我们外层循环n次一定能保证求出多源最短路径。