Floyd算法重建路径

这是章学勤的blog。Floyd算法为图中求最短路径的算法,但并不关心路径细节,百科上说只要稍加修改便可实现路径重建。但水平太次自己修改实现暂时有点难度,后来查了维基百科后发现有现成的解决方案,直接套用一下便可输出路径。标红处为与原算法的主要区别。第一张图片是解决的问题,接下来是输入的数据,然后是源代码,最后是结果。





10 14
0 1 2 3 4 5 6 7 8 9
0 1 45
0 2 35
0 3 50
1 2 20
1 5 90
1 8 70
2 4 50
3 4 50
5 6 20
5 7 50
5 8 50
6 0 40
6 3 40
9 8 35


#include<stdio.h>
#include<iostream>
#include<fstream>
#include<limits.h> 
using namespace std;


#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 10


typedef struct ArcCell {
int adj;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];


typedef struct {
int vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
} MGraph;


typedef struct {
bool path;
} PathCell, PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 


typedef struct {
int distance;
} DistanceCell, DistanceMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];


typedef struct {
int path;
} RecordCell, RecordMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];


void CreateDG(MGraph &G);
void ShortestPath_FLOYD(MGraph G, PathMatrix &P, DistanceMatrix &D, RecordMatrix &record);
void getPath(RecordMatrix record, int v1, int v2);


int main() {
RecordMatrix record;
MGraph mg;
CreateDG(mg);
PathMatrix p;
DistanceMatrix d;
ShortestPath_FLOYD(mg, p, d, record);
cout << "请输入要求解的两个顶点的序列号" << endl; 
int vertex1, vertex2;
cin >> vertex1;
cin >> vertex2;
if(d[vertex1][vertex2].distance == INFINITY) { 
cout << "该地点无法到达" << endl;  
return 0;
}
else printf("所求最短路径为:%d\n", d[vertex1][vertex2].distance);
cout << "经过路径为: ";
cout <<  vertex1 << " -> ";
getPath(record, vertex1, vertex2);
cout <<  vertex2 << endl;
}


void CreateDG(MGraph &G) {
ifstream cin("./graph.txt");
int v1, v2, w; //依次存放输入弧时,其所对应的顶点与权重 
cout << "正在构造有向图" << endl;
cout << "请输入有向图的顶点数、弧数" << endl;
cin >> G.vexnum;
cin >> G.arcnum;
cout << "请依次输入每个顶点的值:" << endl; 
for(int i=0; i<G.vexnum; ++i) cin >> G.vexs[i]; 
for(int i=0; i<G.vexnum; ++i)
for(int j=0; j<G.vexnum; ++j) {
if(i == j) G.arcs[i][j].adj = 0;
else G.arcs[i][j].adj = INFINITY;
}
cout << "请依次弧所依赖的两个顶点的序号及其权重" << endl;
for(int i=0; i<G.arcnum; ++i) {
cin >> v1;
cin >> v2;
cin >> w;
G.arcs[v1][v2].adj = w;
}
}


void ShortestPath_FLOYD(MGraph G, PathMatrix &P, DistanceMatrix &D, RecordMatrix &record) {
for(int v=0; v<G.vexnum; ++v) {
for(int w=0; w<G.vexnum; ++w) {
record[v][w].path = w;
D[v][w].distance = G.arcs[v][w].adj;
for(int u=0; u<G.vexnum; ++u) P[v][w][w].path = false;
if(D[v][w].distance < INFINITY)
P[v][w][v].path = P[v][w][w].path = true;
}
}
for(int u=0; u<G.vexnum; ++u)
for(int v=0; v<G.vexnum; ++v)
for(int w=0; w<G.vexnum; ++w)
if(D[v][u].distance+D[u][w].distance < D[v][w].distance && D[v][u].distance!=INFINITY && D[u][w].distance!=INFINITY) {
D[v][w].distance = D[v][u].distance+D[u][w].distance;
record[v][w].path = record[v][u].path;
for(int i=0; i<G.vexnum; ++i)
P[v][w][i].path = P[v][u][i].path || P[u][w][i].path;
}
}


void getPath(RecordMatrix record, int v1, int v2) {
int temp = record[v1][v2].path;
if(temp == v2) return;
cout << temp << " -> ";
getPath(record, temp, v2);
return;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值