如果您只需要计算存在多少不同的最短路径,您可以在shortestPath 数组之外保留一个count 数组。这是对wiki 的伪代码的快速修改。
procedure FloydWarshall ()
for k := 1 to n
for i := 1 to n
for j := 1 to n
if path[i][j] == path[i][k]+path[k][j] and k != j and k != i
count[i][j] += 1;
else if path[i][j] > path[i][k] + path[k][j]
path[i][j] = path[i][k] + path[k][j]
count[i][j] = 1
如果您需要找到所有路径的方法,您可以为每一对存储一个类似vector/arraylist 的结构以展开和折叠。这是对同一 wiki 的伪代码的修改。
procedure FloydWarshallWithPathReconstruction ()
for k := 1 to n
for i := 1 to n
for j := 1 to n
if path[i][k] + path[k][j] < path[i][j]
path[i][j] := path[i][k]+path[k][j];
next[i][j].clear()
next[i][j].push_back(k) // assuming its a c++ vector
else if path[i][k] + path[k][j] == path[i][j] and path[i][j] != MAX_VALUE and k != j and k != i
next[i][j].push_back(k)
注意:如果k==j 或k==i,这意味着,您正在检查path[i][i]+path[i][j] 或path[i][j]+path[j][j],两者都应该等于path[i][j],并且不会被推入next[i][j]。
应该修改路径重建以处理vector。在这种情况下,计数将是每个 vector 的大小。这是对来自同一 wiki 的伪代码 (python) 的修改。
procedure GetPath(i, j):
allPaths = empty 2d array
if next[i][j] is not empty:
for every k in next[i][j]:
if k == -1: // add the path = [i, j]
allPaths.add( array[ i, j] )
else: // add the path = [i .. k .. j]
paths_I_K = GetPath(i,k) // get all paths from i to k
paths_K_J = GetPath(k,j) // get all paths from k to j
for every path between i and k, i_k in paths_I_K:
for every path between k and j, k_j in paths_K_J:
i_k = i_k.popk() // remove the last element since that repeats in k_j
allPaths.add( array( i_k + j_k) )
return allPaths
注意:path[i][j] 是一个邻接列表。在初始化path[i][j] 的同时,您还可以通过在数组中添加-1 来初始化next[i][j]。例如,next[i][j] 的初始化将是
for every edge (i,j) in graph:
next[i][j].push_back(-1)
这将处理一条边作为最短路径本身。您必须在路径重建中处理这种特殊情况,这就是我在 GetPath 中所做的。
编辑:“MAX_VALUE”是距离数组中的初始化值。