求最短路径之——Floyd算法

要求有向网中每两个顶点之间的最短距离,用Dijkstra算法的话,只需要将每个顶点都作为一次源点就可以,用Floyd算法的话,虽然在时间复杂度上和Dijkstra算法一样,但是形式上更为简便,整体性更好。下面是代码:

文件"graph.h"

#include<iostream> #include<string> using namespace std; const int MAX=99999; const int MAX_VEX_NUM=20; class MGraph { private: string vexs[MAX_VEX_NUM];//顶点数组 int arcs[MAX_VEX_NUM][MAX_VEX_NUM];//邻接矩阵 int vexnum;//顶点数 int arcnum;//边数 public: void Create_MG() { int i,j,k; cout<<"输入图的顶点数和边数:"; cin>>vexnum>>arcnum; cout<<"输入各个顶点的民称:"; for(i=0;i<vexnum;i++) cin>>vexs[i]; for(i=0;i<vexnum;i++) for(int j=0;j<vexnum;j++) arcs[i][j]=MAX; //上面是初始化邻接矩阵 for(k=0;k<arcnum;k++) { cout<<"输入每条边对应的始点和终点以及该边的权值:"; string v1,v2; int w; cin>>v1>>v2>>w; i=Locate_Vex(v1); j=Locate_Vex(v2); while(i<0|| i>vexnum-1 || j<0 || j>vexnum-1) { cout<<"结点位置输入错误,重新输入: "; cin>>v1>>v2>>w; i=Locate_Vex(v1); j=Locate_Vex(v2); } arcs[i][j]=w; } cout<<"图构造完成"<<endl; } int Locate_Vex(string x) //用于确定顶点在顶点数组中的位置 { for(int k=0;vexs[k]!=x;k++); return k; } /*------------------------------------------------------------------ / / 弗洛伊德(Floyd)算法:求有向网中每两个顶点之间的距离 / 第一次,判别(Vi,Vo)和(Vo,Vj),即判断vi->vo->vj路径是否存在,若存在 / 则比较vi->vj 和 vi->vo->vj的长度,短的作为vi到vj的之间顶点的序号 / 不大于0的最短路径。第二次,再增加一个顶点v1,也就是说,如果(vi,..,v1) / 和(v1,..,vj)分别是当前找到的中间顶点序号不大于0的最短路径,那么 / (vi,...,v1,...,vj)就有可能是从vi到vj的中间顶点 不大于1的最短路径。将 / 它和已经得到的从vi到vj的中间顶点不大于0的最短路径比较,短的为从vi / 到vj的中间顶点不大于1的最短路径。第三次,在增加一个顶点v2,继续比较。 / 依此类推,在经过n次这样的比较之后,最后求得的就是vi到vj的最短路径。 / /------------------------------------------------------------------*/ void Floyd_Short_Path(int path[20][20],int Dist[20][20]) { //Dist[v][w]保存从顶点v到w的最短路径长度 //path[v][w]保存到达w的前一个顶点 for(int v=0;v<vexnum;v++) for(int w=0;w<vexnum;w++) { Dist[v][w]=arcs[v][w]; if(Dist[v][w]<MAX) path[v][w]=v; else path[v][w]=-1; } for(int u=0;u<vexnum;u++) for(int v=0;v<vexnum;v++) for(int w=0;w<vexnum;w++) if(v!=w && Dist[v][u]+Dist[u][w]<Dist[v][w]) { Dist[v][w]=Dist[v][u]+Dist[u][w]; path[v][w]=path[u][w]; } } //下面输出两顶点间最短路径的过程的算法,是利用了path[][]数组的特点,进行逆序输出 void Print(int path[20][20],int Dist[20][20]) { cout<<"___输出每两个顶点之间的最短路径和经过的顶点___"<<endl; int j,a[10],c; for(int v=0;v<vexnum;v++) for(int w=0;w<vexnum;w++) if(Dist[v][w]<MAX) { cout<<"顶点"<<vexs[v]<<"到顶点"<<vexs[w]<<"的最短路径长为"<<Dist[v][w]<<endl; cout<<"经过的顶点为:"; j=w; c=0; while(path[v][j]!=-1) { a[c]=path[v][j]; j=path[v][j]; c++; } for(j=c-1;j>=0;j--) cout<<vexs[a[j]]<<"->"; cout<<vexs[w]<<endl; } } };

测试文件"main.cpp"

#include"graph.h" int main() { MGraph G; G.Create_MG(); int Dist[20][20]; int path[20][20]; cout<<"求有向网中没两个顶点之间的最短路径"<<endl; G.Floyd_Short_Path(path,Dist); cout<<endl; G.Print(path,Dist); cout<<endl; return 0; }

下面是输入和输出结果:

输入图的顶点数和边数:6 8 输入各个顶点的民称:v1 v2 v3 v4 v5 v6 输入每条边对应的始点和终点以及该边的权值:v1 v3 10 输入每条边对应的始点和终点以及该边的权值:v1 v5 30 输入每条边对应的始点和终点以及该边的权值:v1 v6 100 输入每条边对应的始点和终点以及该边的权值:v2 v3 5 输入每条边对应的始点和终点以及该边的权值:v3 v4 50 输入每条边对应的始点和终点以及该边的权值:v5 v4 20 输入每条边对应的始点和终点以及该边的权值:v4 v6 10 输入每条边对应的始点和终点以及该边的权值:v5 v6 60 图构造完成 求有向网中没两个顶点之间的最短路径 ___输出每两个顶点之间的最短路径和经过的顶点___ 顶点v1到顶点v3的最短路径长为10 经过的顶点为:v1->v3 顶点v1到顶点v4的最短路径长为50 经过的顶点为:v1->v5->v4 顶点v1到顶点v5的最短路径长为30 经过的顶点为:v1->v5 顶点v1到顶点v6的最短路径长为60 经过的顶点为:v1->v5->v4->v6 顶点v2到顶点v3的最短路径长为5 经过的顶点为:v2->v3 顶点v2到顶点v4的最短路径长为55 经过的顶点为:v2->v3->v4 顶点v2到顶点v6的最短路径长为65 经过的顶点为:v2->v3->v4->v6 顶点v3到顶点v4的最短路径长为50 经过的顶点为:v3->v4 顶点v3到顶点v6的最短路径长为60 经过的顶点为:v3->v4->v6 顶点v4到顶点v6的最短路径长为10 经过的顶点为:v4->v6 顶点v5到顶点v4的最短路径长为20 经过的顶点为:v5->v4 顶点v5到顶点v6的最短路径长为30 经过的顶点为:v5->v4->v6 Press any key to continue

所生成的有向网如下:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值