The Wikipedia article is terrible. In addition to the incorrect representation (in my opinion) of the canonical form of the Floyd-Warsall algorithm, it is an erroneous pseudocode.
Its much simpler (and more directly) not to iterate over indexes, but over vertices. In addition, each predecessor (usually denoted by Ο , not next ) should point to it, well, the predecessor, and not to a temporary temporary vertex.
With that in mind, we can fix their broken pseudo-code.
for each vertex v dist[v][v] β 0 for each edge (u,v) dist[u][v] β w(u,v) // the weight of the edge (u,v) for each vertex k for each vertex i for each vertex j if dist[i][k] + dist[k][j] < dist[i][j] then dist[i][j] β dist[i][k] + dist[k][j] next[i][j] β next[k][j]
Note that Ive changed the three nested loops to iterate over the vertices, not the indexes, and Ive fixed the last row to refer to the previous node, and not to any intermediate node.
An explanation of why this is correct and how the predecessor matrix works can be found on Algoritmy.net .
The above requires some initialization. Fortunately, this is easy, since we already know the first predecessor of each node: if theres a direct path from i to j , then i is the predecessor of j . If there is no direct path, then there is no predecessor.
for each vertex i for each vertex j if w(u,v) = β then next[i][j] β NIL else next[i][j] β i
NIL is just a placeholder for any value other than vertices. In object oriented code, this will usually be a null reference / pointer. When implementing a graph as an adjacency matrix, it can be any index that does not correspond to a vertex, for example. -1 or | V | +1
They also provide corrected reconstruction of the path:
function path(P, i, j) if i = j then write i else if next[i][j] = NIL then write "no path exists" else path(P, i, P[i][j]) write j