程序小白,希望和大家多交流,共同学习
//弗洛伊德(floyd)算法,用于计算最短路径
#include<iostream>
#include<string>
#include<iostream>
#include<iomanip>
#define MAX_VN 50
#define INF 32767
using namespace std;
typedef string VertexData;
struct AdjMatrix{
VertexData vertex[MAX_VN];
int arcs[MAX_VN][MAX_VN];
int verNum, arcNum;
};
void createAdjMatrix(AdjMatrix &G);
int locateVertex(AdjMatrix &G, VertexData data);
void outputAdjMatrix(AdjMatrix &G);
//Floyd
void floyd(const AdjMatrix &G);
string getVertex(const AdjMatrix &G, int i);
int main(){
/*
6 10
v1 v2 v3 v4 v5 v6
v1 v2 5
v1 v4 7
v2 v3 4
v3 v1 8
v3 v6 9
v4 v3 5
v4 v6 6
v5 v4 5
v6 v1 2
v6 v5 1
*/
AdjMatrix G;
createAdjMatrix(G);
outputAdjMatrix(G);
floyd(G);
return 0;
}
void createAdjMatrix(AdjMatrix &G){
cout << "输入顶点数和弧的条数:";
cin >> G.verNum >> G.arcNum;
cout << "输入顶点信息:";
for (int i = 0; i < G.verNum; i++){
cin >> G.vertex[i];
}
for (int i = 0; i < G.verNum; i++){
for (int j = 0; j < G.verNum; j++){
G.arcs[i][j] = INF;
}
}
cout << "输入弧的信息:";
VertexData u, v;
int w, j, k;
for (int i = 0; i < G.arcNum; i++){
cin >> u >> v >> w;
j = locateVertex(G, u);
k = locateVertex(G, v);
G.arcs[j][k] = w;
}
}
int locateVertex(AdjMatrix &G, VertexData data){
for (int i = 0; i < G.verNum; i++){
if (G.vertex[i] == data){
return i;
}
}
return -1;
}
void outputAdjMatrix(AdjMatrix &G){
for (int i = 0; i < G.verNum; i++){
for (int j = 0; j < G.verNum; j++){
if (G.arcs[i][j] != INF){
printf("%-3d", G.arcs[i][j]);
}
else
cout << "∞ ";
}
cout << endl;
}
}
void floyd(const AdjMatrix &G){
int n = G.verNum;
int dist[n][n];//用来记录到达各个顶点的最短路径
string path[n][n];//用来记录最短路径的路线
for (int i = 0; i < n; i++){//初始化路线和最短路径值
for (int j = 0; j < n; j++){
dist[i][j] = G.arcs[i][j];
//顶点到达自己 是没有意义的
if (i == j){
dist[i][j] = 0;
}
path[i][j] = "";//初始化为不可达
if (dist[i][j] != 0){
path[i][j] = getVertex(G, i) + getVertex(G, j);
}
}
}
//按照AdjMatrix的信息更新dist和path
//更新:将第k行逐个扫描,每扫描一个就紧接着扫描它的邻接点
//当邻接点的权值回和原点的权值和小于dist中的值就更新dist同时更新path
//达到的目的就是使可达点的路径值最小,同时记录这条路径
for (int k = 0; k < n; k++){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
if (i != j && dist[i][j] > dist[i][k] + dist[k][j]){
dist[i][j] = dist[i][k] + dist[k][j];
string sub = getVertex(G, k);
int index = path[i][k].find(sub);
path[i][j] = path[i][k].substr(0, index) + path[k][j];
}
}
}
}
//输出路径值和路线
cout << "D |";
for (int i = 0; i < n; i++){
cout << setw(9) << i;
}
cout << endl;
for (int i = 0; i < n; i++){
cout << "---------";
}
cout <<endl;
for (int i = 0; i < n; i++){
cout << i << " |";
for (int j = 0; j < n; j++){
cout << setw(9) << dist[i][j];
}
cout << endl;
}
cout << endl;
cout << "P |";
for (int i = 0; i < n; i++){
cout << setw(9) << i;
}
cout << endl;
for (int i = 0; i < n; i++){
cout << "---------";
}
cout << endl;
for (int i = 0; i < n; i++){
cout << i << " |";
for (int j = 0; j < n; j++){
cout << setw(9) << path[i][j];
}
cout << endl;
}
cout << endl;
}
string getVertex(const AdjMatrix &G, int i){
if (i >= 0 && i < G.verNum){
return G.vertex[i];
}
}