CHAPTER_10 提高篇(4)——图算法专题
10.4.4Floyd算法
Floyd算法(弗洛伊德算法)用来解决全源最短路径问题,即对于给定的图G(V,E),求任意两点u,v之间的最短路径长度,时间复杂度是O(n^3)。由于n^3的时间复杂度很高,因此顶点数n基本被限制在200以内,因此使用邻接矩阵实现Floyd算法非常合适。
Floyd算法基于这样一个事实:如果存在顶点 k ,使得以k作为中介点时顶点 i 和顶点 j 的当前最短路径距离缩短,则使用顶点 k 作为顶点 i 和顶点 j 的中介点,即当dis[i][k]+dis[k][j]<dis[i][j]时,令dis[i][j]=dis[i][k]+dis[k][j](其中dis[i][j]表示从顶点i到j最短距离)。
如下图所示,从V1到V4的距离为3,而以V2为中介点时可以使V1到V4的距离缩短为2,那么就把V1到V4的距离从3优化到2,即当dis[1][2]+dis[2][4]<dis[1][4],令dis[1][4]=dis[1][2]+dis[2][4]。
可以看出,Floyd算法的思想很简洁,可以写出代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3fffffff;
const int MAXV=200; //MAXV为最大顶点数
int n,m; //n为顶点数,m为边数
int dis[MAXV][MAXV]; //dis[i][j]表示顶点i和j的最短距离
void Floyd() {
for(int k=0;k<n;k++) {
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if(dis[i][k]!=INF&&dis[k][j]!=INF&&dis[i][k]+dis[k][j]<dis[i][j]) {
dis[i][j]=dis[i][k]+dis[k][j]; //找到更短路径
}
}
}
}
}
//假设图模型为有向图
int main() {
int u,v,w;
fill(dis[0],dis[0]+MAXV*MAXV,INF); //dis二维数组赋初值
cin>>n>>m;
for(int i=0;i<n;i++) {
dis[i][i]=0; //矩阵对角线初始化为0
}
for(int i=0;i<m;i++) { //输入边
cin>>u>>v>>w;
dis[u][v]=2;
}
Floyd(); //算法入口
for(int i=0;i<n;i++) { //输出全源最短路径
for(int j=0;j<n;j++) {
cout<<dis[i][j]<<' ';
}
cout<<endl;
}
return 0;
}