- 问题
用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵)
- 解析
任意节点i到j的最短路径两种可能:
直接从i到j;(不可能)
从i经过若干个节点k到j。
map(i,j)表示节点i到j最短路径的距离,对于每一个节点k,检查map(i,k)+map(k,j)小于map(i,j),如果成立,map(i,j) = map(i,k)+map(k,j);遍历每个k,每次更新的是除第k行和第k列的数。
3. 设计
距离矩阵:
void floyd()
{
int i, j, k;
for(k from 1 to n)
{
for(i from 1 to n)
{
for(j from 1 to n)
{
if(从i到j经过k的距离比目前从i到j的距离短)
e[i][j] = e[i][k] + e[k][j];//更新从i到j的距离
}
}
}
}
- 分析
三重for循环,时间复杂度:O(n3);空间复杂度:O(n2); - 源码
#include<iostream>
#include<fstream>
using namespace std;
int e[999][999];
int m, n, u, v, l;//n个顶点,m条边,输入m行,一行有顶点u,v,距离l
const int inf=0x3f3f3f3f;
ifstream fin("input.txt");
ofstream fout("output.txt");
void init()
{
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=n; ++j)
{
if(i == j)
e[i][j] = 0;
if(i != j)
e[i][j] = inf;
}
}
}
void floyd()
{
int i,j,k;
for(k=1; k<=n; ++k)
{
for(i=1; i<=n; ++i)
{
for(j=1; j<=n; ++j)
{
if(e[i][k] < inf && e[k][j] < inf && e[i][j] > e[i][k] + e[k][j])
e[i][j] = e[i][k] + e[k][j];
}
}
}
}
int main()
{
fin >> n >> m;
init();
for(int i=1; i<=m; ++i)
{
fin >> u >> v >> l;
e[u][v] = l;
}
floyd();
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
fout << e[i][j] << " ";
}
fout << endl;
}
fin.close();
fout.close();
return 0;
}