Floyd是用于解决多源最短路问题的一种算法,它的过程是:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵(这意味着一般地,Floyd算法要求用邻接矩阵存图)。
设n=|V|,从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
那么如何实现呢?首先,定义一个n*n邻接矩阵,表示各点之间的最短距离,其中a[i,j]为点i到点j的最短距离,且初始状态是无边的(即对于任意点对i,j都有a[i][j]= +∞)。随着读入矩阵会记录各点之间边的信息,然后对于每一对顶点u和v,我们采用松弛操作,看是否存在一个顶点w使得从u到w再到v比从u到v的已知路径更短,如果是则更新它;在松弛中,我们会运用到动态规划的思想(简单来说就是由局部最优解推全局最优解,动态规划的使用要求问题满足以下两个性质:1、无后效性;2、最优子结构),状态转移方程(即上文所说的公式)为map[u][v]=min(map[u][w]+map[w][v],map[u][v])。通过不断松弛,可以将这个矩阵更新为一个最优的距离矩阵。
由于首先我们要枚举每一个点对,这里相当于枚举n^2次,对于每个点对我们还要枚举所有其它点,这里又要枚举n次,故时间复杂度为O(n^3);用邻接矩阵存图,空间复杂度为O(n^2)。
代码如下:
(C++ Code)
1 voidFloyd(int n)
//n为点数
2 {
3 for(int k=1;k<=n;k++)
4 for(int i=1;i<=n;i++)
5 for(int j=1;j<=n;j++)
6 map[i][j]=min(map[i][k]+map[k][j],map[i][j]);
//要注意枚举的次序,点对在第二、三重循环
7 }