所有点对之间的最短路算法
Floyd_warshall 算法
使用条件及时间复杂度
Floyd warshall 算法适用于无负环的有向图中的所有点对之间的最短路径,容易看出时间复杂度为O(v^3)。
代码实现
void floyd_warshall()
{
int tmp;
for(int k = 1; k <= n; ++k)
{
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
//松弛操作;
{
tmp = mp[i][k] + mp[k][j];
if(tmp < mp[i][j])
{
mp[i][j] = tmp;
}
}
}
}
}
}
算法正确性的证明
我们使用归纳法需要证明:
当最外层循环k完成后,对于所有点对,我们已经求出中间节点只包含点{1,2,3,,,,,k}的最短路径。
首先,在第1次循环开始前,所有点对中间节点只包含点{0}的最短路径,即,所有节点对之间的最短路径不包含任何中间节点。
然后,假设,k - 1次循环完成保证上述性质成立。
然后,在第k次循环中,
若松弛操作不成立,则节点对之间最短路径只包含{1,2,3,,,,k-1}之间的节点,也即是只包含{1,2,3,,,,k}之间的节点;
若松弛操作成立,因为(i -> k)最短路径只包含{1,2,3,,,,k-1}之间的节点,(k -> j)最短路径只包含{1,2,3,,,,k-1}之间的节点。
松弛完成后,(i -> j)节点对之间最短路径只包含{1,2,3,,,,k}之间的节点.
证毕。
通过以上性质,可以得出:当最外层循环n完成后,对于所有点对,我们已经求出中间节点只包含点{1,2,3,,,,,n}的最短路径,也即是最短路径的定义。
如有错误,恳请指正。