版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
算法前提
- MAXN,数组最大长度
- INF,无穷大数值
- map数组存放图的邻接矩阵
- path数组存放从i到j的最短路径起始点
- n,顶点数
- k,边数
- begin,起点下标
- end,终点下标
- 栈stk,保存路径节点
算法描述
- 初始化无边顶点间路径为map[ i ][ j ]=INF
- 初始化无边顶点间可达矩阵path[ i ][ j ]=-1
- 循环n次,循环变量为k
- 第二层循环,循环n次,循环变量为i
- 第三层循环,循环n次,循环变量为j
- 比较i到j的距离与i到k再到j的距离,使map[ i ][ j ]更新为最短距离,若需要更新,path[ i ][ j ] = k
- 循环结束
- 输出map[ begin][ end ]
- 根据path数组查找路径并输出
样例输入
- 顶点数n
- 边数k
- 起点begin,终点end
- k组数据,输入a b len,为从a到b的距离len
5
6
0 1
0 2 60
0 3 30
0 4 50
1 2 20
1 4 10
3 4 10
样例输出
- 最短路径值
- 最短路径经过的下标
50
0->3->4->1
代码
#include <iostream>
#include <algorithm>
#include <stack>
#define MAXN 200
#define INF 99999
using namespace std;
int map[MAXN][MAXN],path[MAXN][MAXN];//图和路径的邻接矩阵
int n,k,begin,end;//顶点数,边数
stack<int> stk;//保存路径
void floyd(){
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int len=map[i][k]+map[k][j];//中间路径
if(len<map[i][j]&&i!=j){
map[i][j]=len;//路长更新
path[i][j]=path[k][j];//路径更新
}
}
}
}
cout<<map[begin][end]<<endl;//长度输出
//路径输出
int p=end;
stk.push(p);
while(stk.top()!=begin){
p=path[begin][p];
stk.push(p);
}
while(!stk.empty()){
cout<<stk.top();
stk.pop();
if(!stk.empty()) cout<<"->";
}
}
int main(){
cin>>n;//顶点数
cin>>k;//边数
cin>>begin>>end;//始终下标
for(int i=0;i<MAXN;i++){
fill(map[i],map[i]+MAXN,INF);//初始化路径不可达
fill(path[i],path[i]+MAXN,-1);
}
for(int i=0;i<k;i++){
int a,b,len;
cin>>a>>b>>len;//输入路径
map[a][b]=map[b][a]=len;
path[a][b]=a;
path[b][a]=b;
}
floyd();
return 0;
}