弗洛伊德算法模板 (Floyd-Warshall算法)
背景:
现有一个单向有向图:
我们用一个n*n邻接矩阵标记为数组a[n+1][n+1]来表示它:a[i][i]都为0
现在我们以地点1为中介点,让地点i通过地点1到达地点j(i->1->j):
用循环表示为:
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (d[i][1] != inf && d[1][j] != inf) // inf = 0x3f3f3f3f
d[i][j] = min(d[i][j], d[i][1] + d[1][j]);
}
}
我们再以地点2为中介点(i->2->j)
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (d[i][2] != inf && d[2][j] != inf) // inf = 0x3f3f3f3f
d[i][j] = min(d[i][j], d[i][2] + d[2][j]);
}
}
所以我们以所有点为中介点,就得到了最终的Floyd-Warshall算法:
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (d[i][k] != inf && d[k][j] != inf) // inf = 0x3f3f3f3f
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
另外需要注意的是:Floyd-Warshall算法不能解决带有“负权回路”(或者叫“负权环”)的图,因为带有“负权回路”的图没有最短路。