一、背景介绍
弗洛伊德算法(Floyed’s algorithm)是一种用来寻找图中任意两点之间最短路径的算法。它是一种动态规划算法【将小规模问题的解存储在内存中,等到大问题的解直接拿来有效利用】,通过比较不同的路径长度来逐步更新并找到最短路径。Floyed算法适用于求解图(有向图和无向图)中任意两端点之间的最短路径问题。
二、算法介绍
- 初始化一个二维矩阵,称为距离矩阵,用于记录任意两点之间的最短路径长度。
- 将距离矩阵初始化为图中各边的权重值,如果两点之间没有直接连接,则将距离设置为一个无穷大的值。
- 对于图中的每个顶点 i,以顶点 i 作为中间节点,遍历所有顶点对 (j, k),尝试通过顶点 i 来更新从顶点 j 到顶点 k 的最短路径长度。如果通过顶点 i 可以获得更短的路径,则更新距离矩阵中对应的路径长度。
例如,对于距离矩阵中的元素 distance[j][k],更新公式如下:
distance[j][k] = min(distance[j][k], distance[j][i] + distance[i][k]) - 重复上述步骤,直到通过所有的顶点作为中间节点时都不能找到更短的路径。
- 最终,完成上述步骤后,距离矩阵中记录的就是任意两点之间的最短路径长度。
三、要点
- 需要注意的是,距离矩阵中的值可能会被更新多次,直到达到最短路径长度。
- 若在距离矩阵中的对角线上存在负数,表示图中存在负权回路,即存在形成一个环,使得环上的边权重总和小于零的情况,此时弗洛伊德算法将无法得出正确结果。
- 算法的时间复杂度为O(|n|^3),其中|n|是图中顶点的个数。这使得弗洛伊德算法更适用于解决顶点数量较少的问题,即n<200比较合适。
四、实验
#include <bits/stdc++.h>
using namespace std;
const int maxn=310;
int d[maxn][maxn];
int n,m,T,x,y,v;
int main()
{
scanf("%d%d%d",&n,&m,&T);
memset(d,0x7f7f7f7f,sizeof(d));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&v);
d[x][y]=v;
}
//floyed算法
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
{
d[j][k]=min(d[j][k],d[j][i]+d[i][k]);//注意题中所问题的问题,求最短路径中,权值最大的边
}
for(int i=1;i<=T;i++)
{
scanf("%d%d",&x,&y);
if(d[x][y]==0x7f7f7f7f)
{
cout<<-1<<endl;
}else{
cout<<d[x][y]<<endl;
}
}
return 0;
}