介绍
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。
大体思路
- 构造邻接矩阵:首先,根据图的连接情况构造一个邻接矩阵A,其中A[i][j]表示顶点i到顶点j的直接距离(如果存在边),否则为无穷大(表示不可达)。
- 初始化矩阵:开始将邻接矩阵初始化为相邻顶点间的距离矩阵。
- 遍历中间节点:对于图中的每一个顶点k(作为中间点),遍历所有顶点对(i, j),检查是否存在从i到k再到j的路径比已知的路径更短。如果存在,则更新D[i][j]。
- 状态转移方程:A[i][j] = min(A[i][j], A[i][k] + A[k][j]),其中k为中间节点(中转点)。
- 输出最短路径:在完成所有遍历后,距离矩阵D中存储的就是任意两点之间的最短距离。
实现步骤
1.0初始化
2.0核心算法
3.0打印输出
源代码
#include<iostream> #include<vector> #include<climits> // |-BFS(无权图) // |- 单源最短路径 -| //最短路径问题 -| |-Dijkstra(带权图,无权图) // | // |- 各顶点间最短路径 - Floyd算法(带权图,无权图) void Floyd(int n,std::vector<std::vector<int>>&A,std::vector<std::vector<int>>&path){ //k是指第k个中转点 for(int k = 0;k<n;k++){ //起始点i for(int i=0;i<n;i++){ //目的点j for(int j=0;j<n;j++){ if(A[i][j]>A[i][k]+A[k][j]){ A[i][j] = A[i][k]+A[k][j]; path[i][j] = k; } } } } } int main() { int n; std::cin>>n; std::vector<std::vector<int>>A(n,std::vector<int>(n,INT16_MAX)); std::vector<std::vector<int>>path(n,std::vector<int>(n,-1)); for(int i = 0;i<n;i++){ for(int j = 0;j<n;j++){ int m; std::cin >>m; if(m!=-1){ A[i][j] = m; } } } Floyd(n,A,path); for(int i = 0;i<n;i++){ for(int j = 0;j < n;j++){ if(A[i][j]==INT16_MAX){ std::cout << "*"<<" "; } else{ std::cout <<A[i][j]<<" "; } } std::cout << " "; for(int j = 0;j<n;j++){ std::cout << path[i][j]<<" "; } std::cout << std::endl; } return 0; }