大话数据结构——最短路径~弗洛伊德Floyd算法~O(n ^ 3)~2020.7.16

按我的个人理解,Dijkstra算法关注的是单元最短路径问题,而Floyd算法关注的是多元最短路径问题,即一个是从某个顶点出发求出其达到其他顶点的最短路径,一个是从每个顶点出发到达其他顶点的最短路径。

迪杰斯特拉算法与弗洛伊德算法的核心,都在于关注中继顶点即,引入中继顶点之后,反而缩短了两个顶点之间的距离。举个例子,比如从v0->v5,直接距离是99,而从v0->v3距离是4,从v3->v5距离是27,显然4+27<<99,最短路径的思想便是如此,不断地引入中继顶点使图松弛,最终达到求出最短路径的目的。

下面直接放出代码:

#include <iostream>
#include <iomanip>
using namespace std;
typedef int EdgeType ;
typedef int vertexType;
const int MAXVEX = 105;
const int INFINITY = 65535;
struct MGraph{
 EdgeType arc[MAXVEX][MAXVEX];//边表 
 vertexType vertexes[MAXVEX];//顶点表
 int numVertexes,numEdges; 
};
void createMGraph(MGraph *G){
 cout<<"输入顶点与边的个数:";
 cin>>G->numVertexes>>G->numEdges;
// cout<<"输入"<<G->numVertexes<<"个顶点的信息:";
// for(int i=0;i<G->numVertexes;i++){
//  cin>>G->vertexes[i];
// }
 for(int i=0;i<G->numVertexes;i++){
  for(int j=0;j<G->numVertexes;j++){
   if(i==j) G->arc[i][j] = 0;
   else  G->arc[i][j]=INFINITY;
  }
 }
 for(int i=0;i<G->numEdges;i++){
  int s,e,w;
  cout<<"输入边(vi,vj)的信息vi,vj及边权w:";
  cin>>s>>e>>w;
  G->arc[s][e] = w;
  G->arc[e][s]=G->arc[s][e];
 }
}
int P[MAXVEX][MAXVEX];//P存储每个顶点到任意顶点的最短路径 
int D[MAXVEX][MAXVEX];//D存储每个顶点到任意顶点的最短路径长度 
void ShortestPath_Floyd(MGraph *G){
 for(int i=0;i<G->numVertexes;i++){
  for(int j=0;j<G->numVertexes;j++){
   D[i][j] = G->arc[i][j];/*未松弛前的“最短”路径长度即为原弧长*/
   P[i][j] = j;   /*路径即为起点到中典*/
  }
 }/*初始化操作*/
 for(int i=0;i<G->numVertexes;i++){/*第一层循环模拟的是中转顶点*/
  for(int j=0;j<G->numVertexes;j++){/*第二层模拟起点*/ 
   for(int k=0;k<G->numVertexes;k++){/*模拟终点*/
    if(D[j][k]>D[j][i]+D[i][k]){/*松弛:倘若经过中转顶点
    到达终点的权值小于直接到达终点的权值,则执行以下操作。*/
     D[j][k] = D[j][i]+D[i][k];
     P[j][k] = P[j][i];/*路径设置为顶点i的下标*/
    }
   }
  }
 }
}
void PrintD(int n){
 cout<<"输出每个顶点到各个顶点的最短路径权值:"<<endl;
 cout<<setw(3)<<' ';
 for(int i=0;i<n;i++){
  cout<<setw(3)<<i;
 }
 cout<<endl;
 for(int i=0;i<n;i++){
  cout<<setw(3)<<i;
  for(int j=0;j<n;j++){
   cout<<setw(3)<<D[i][j];
  }
  cout<<endl;
 } 
}
void showPath(int n){
 for(int i=0;i<n;i++){
  for(int j=i+1;j<n;j++){
   cout<<"v"<<i<<"->v"<<j<<" weitght:"<<D[i][j]<<endl;
   int k=P[i][j];
   cout<<"Path:"<<i;
   while(k!=j){
    cout<<"->"<<k;
    k=P[k][j];
   }
   cout<<"->"<<j<<endl;
  }
 }
}
int main()
{
 MGraph M;
 createMGraph(&M);
 ShortestPath_Floyd(&M);
 PrintD(M.numVertexes);
 showPath(M.numVertexes);
 return 0;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值