Floyd动态规划算法C++代码实现
样例输入
输入顶点个数
输入顶点数据域
输入边个数
输入每条边的两个临界点及距离(权重)
5
A B C D E
6
A B 5
A C 6
A D 3
D E 10
E C 15
C B 7
样例输出
输出两顶点间最短距离
0 5 6 3 13
5 0 7 8 18
6 7 0 9 15
3 8 9 0 10
13 18 15 10 0
C++代码
#include<iostream>
using namespace std;
#include<limits.h>
struct Adjgraph { //邻接矩阵
char vertlist[100]; //顶点数据域
int edgelist[100][100]; //边表
int n, e; //顶点个数、边个数
};
Adjgraph* CreateAdjgraph() {
Adjgraph* g = new Adjgraph;
cin >> g->n;
for (int i = 0; i < g->n; i++) { //初始化邻接矩阵
cin >> g->vertlist[i];
for (int j = 0; j < g->n; j++) {
if (i != j)
g->edgelist[i][j] = INT_MAX;
else
g->edgelist[i][j] = 0;
}
}
cin >> g->e;
char temp1, temp2;
int weight, adj1, adj2;
for (int i = 0; i < g->e; i++) {
cin >> temp1 >> temp2 >> weight;
for (int j = 0; j < g->n; j++) { //把输入信息转换成邻接矩阵保存
if (temp1 == g->vertlist[j]) adj1 = j;
if (temp2 == g->vertlist[j]) adj2 = j;
}
g->edgelist[adj1][adj2] = weight;
g->edgelist[adj2][adj1] = weight;
}
return g;
}
void Floyd(Adjgraph* g, int D[][100]) { //Floyd动态规划算法
for (int i = 0; i < g->n; i++)
for (int j = 0; j < g->n; j++)
D[i][j] = g->edgelist[i][j];
for (int k = 0; k < g->n; k++)
for (int i = 0; i < g->n; i++)
for (int j = 0; j < g->n; j++)
if (D[i][k] + D[k][j] < D[i][j] && D[i][k] < INT_MAX && D[j][k] < INT_MAX)
D[i][j] = D[i][k] + D[k][j];
}
int main() {
Adjgraph* g = CreateAdjgraph();
int D[100][100]; //用于储存动态规划的两顶点间最短距离
Floyd(g, D);
for (int i = 0; i < g->n; i++) { //输出两顶点间最短距离
for (int j = 0; j < g->n; j++)
printf("%-3d ", D[i][j]);
cout << endl;
}
return 0;
}
总结
Floyd优缺点分析:
优点:比较容易容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
缺点:时间复杂度比较高(n3),不适合计算大量数据,当数据稍微大点儿的时候就可以选择其他的算法来解决问题了,不然也会是超时。
Floyd算法与Dijkstra算法的区别
1.Floyd算法是求任意两点之间的距离,是多源最短路,而Dijkstra(迪杰斯特拉)算法是求一个顶点到其他所有顶点的最短路径,是单源最短路。
2.Floyd算法属于动态规划,我们在写核心代码时候就是相当于推dp状态方程,Dijkstra(迪杰斯特拉)算法属于贪心算法。
3.Dijkstra(迪杰斯特拉)算法时间复杂度一般是o(n^2),Floyd算法时间复杂度是o(n3),Dijkstra(迪杰斯特拉)算法比Floyd算法块。
4.Floyd算法可以算带负权的,而Dijkstra(迪杰斯特拉)算法是不可以算带负权的。并且Floyd算法不能算负权回路。