Floyd算法求解各个顶点之间的最短距离
1.问题
- 用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵)
2.解析
- 路径矩阵:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
- 从图的带权邻接矩阵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来记录两点间的最短路径。
1)初始化矩阵:(自己到自己记为0,无法到达记为ꝏ)2)若只允许经过点1,求任意两点距离
3)若只经过点1,2,求任意两点距离
4)同理,经过1,2,3和经过1,2,3,4,点,任意两点的距离
3.设计
- 伪代码:
- 算法Floyd(W[1…n,1…n])
- //实现计算完全最短器径的Floyd算法
- //输入:不包含长度为负的回路的图的权重矩阵w
- //输出:包含最短路径长度的距离矩阵
- D<-W//如果可以改写W,这一步可以省略
- for k <- l to n do
- for i <- l to n do
- for j <- l to n do
- D[i,j] <- min{D[i,J], D[i,k]+D[k,j]
- }
- return D
4.分析
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);折叠状态转移方程:其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值一般为0
空间复杂度:O(n^2)
5.源码`
#include <bits/stdc++.h>
using namespace std;
const int INF = 99999999;
int main()
{
int e[10][10] , n , m , t1 , t2 , t3;
cin>>n>>m; //n表示顶点个数,m表示边的条数
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n ; j ++)
{
if(i == j)
e[i][j] = 0 ;
else
e[i][j] = INF;
}
for(int i = 1 ; i <= m ; i ++)
{
cin>>t1>>t2>>t3;
e[t1][t2] = t3;
}
for(int k = 1 ; k <= n ; k ++)
{
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n ; j ++)
{
if(e[i][j] > e[i][k] + e[k][j])
e[i][j] = e[i][k] + e[k][j];
}
}
}
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n ; j ++)
{
printf("%3d",e[i][j]);
}
cout<<endl;
}
return 0 ;
}