所有点对之间的最短路算法

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}的最短路径,也即是最短路径的定义。

如有错误,恳请指正。

原文地址:https://www.cnblogs.com/lif323/p/9353546.html