zoukankan      html  css  js  c++  java
  • 最短路径之——Floyd算法(转)

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

    文件"graph.h"

      1 #include<iostream>
    2 #include<string>
    3 using namespace std;
    4
    5 const int MAX=99999;
    6 const int MAX_VEX_NUM=20;
    7 class MGraph
    8 {
    9 private:
    10 string vexs[MAX_VEX_NUM];//顶点数组
    11 int arcs[MAX_VEX_NUM][MAX_VEX_NUM];//邻接矩阵
    12 int vexnum;//顶点数
    13 int arcnum;//边数
    14 public:
    15 void Create_MG()
    16 {
    17 int i,j,k;
    18 cout<<"输入图的顶点数和边数:";
    19 cin>>vexnum>>arcnum;
    20 cout<<"输入各个顶点的民称:";
    21 for(i=0;i<vexnum;i++)
    22 cin>>vexs[i];
    23
    24 for(i=0;i<vexnum;i++)
    25 for(int j=0;j<vexnum;j++)
    26 arcs[i][j]=MAX;
    27 //上面是初始化邻接矩阵
    28
    29 for(k=0;k<arcnum;k++)
    30 {
    31 cout<<"输入每条边对应的始点和终点以及该边的权值:";
    32 string v1,v2;
    33 int w;
    34 cin>>v1>>v2>>w;
    35 i=Locate_Vex(v1);
    36 j=Locate_Vex(v2);
    37
    38 while(i<0|| i>vexnum-1 || j<0 || j>vexnum-1)
    39 {
    40 cout<<"结点位置输入错误,重新输入: ";
    41 cin>>v1>>v2>>w;
    42 i=Locate_Vex(v1);
    43 j=Locate_Vex(v2);
    44 }
    45
    46 arcs[i][j]=w;
    47 }
    48 cout<<"图构造完成"<<endl;
    49 }
    50
    51 int Locate_Vex(string x) //用于确定顶点在顶点数组中的位置
    52 {
    53 for(int k=0;vexs[k]!=x;k++);
    54 return k;
    55 }
    56
    57 /*------------------------------------------------------------------
    58 /
    59 / 弗洛伊德(Floyd)算法:求有向网中每两个顶点之间的距离
    60 / 第一次,判别(Vi,Vo)和(Vo,Vj),即判断vi->vo->vj路径是否存在,若存在
    61 / 则比较vi->vj 和 vi->vo->vj的长度,短的作为vi到vj的之间顶点的序号
    62 / 不大于0的最短路径。第二次,再增加一个顶点v1,也就是说,如果(vi,..,v1)
    63 / 和(v1,..,vj)分别是当前找到的中间顶点序号不大于0的最短路径,那么
    64 / (vi,...,v1,...,vj)就有可能是从vi到vj的中间顶点 不大于1的最短路径。将
    65 / 它和已经得到的从vi到vj的中间顶点不大于0的最短路径比较,短的为从vi
    66 / 到vj的中间顶点不大于1的最短路径。第三次,在增加一个顶点v2,继续比较。
    67 / 依此类推,在经过n次这样的比较之后,最后求得的就是vi到vj的最短路径。
    68 /
    69 /------------------------------------------------------------------*/
    70
    71 void Floyd_Short_Path(int path[20][20],int Dist[20][20])
    72 {
    73 //Dist[v][w]保存从顶点v到w的最短路径长度
    74 //path[v][w]保存到达w的前一个顶点
    75
    76 for(int v=0;v<vexnum;v++)
    77 for(int w=0;w<vexnum;w++)
    78 {
    79 Dist[v][w]=arcs[v][w];
    80 if(Dist[v][w]<MAX)
    81 path[v][w]=v;
    82 else
    83 path[v][w]=-1;
    84 }
    85 for(int u=0;u<vexnum;u++)
    86 for(int v=0;v<vexnum;v++)
    87 for(int w=0;w<vexnum;w++)
    88 if(v!=w && Dist[v][u]+Dist[u][w]<Dist[v][w])
    89 {
    90 Dist[v][w]=Dist[v][u]+Dist[u][w];
    91 path[v][w]=path[u][w];
    92 }
    93 }
    94
    95 //下面输出两顶点间最短路径的过程的算法,是利用了path[][]数组的特点,进行逆序输出
    96 void Print(int path[20][20],int Dist[20][20])
    97 {
    98 cout<<"___输出每两个顶点之间的最短路径和经过的顶点___"<<endl;
    99 int j,a[10],c;
    100 for(int v=0;v<vexnum;v++)
    101 for(int w=0;w<vexnum;w++)
    102 if(Dist[v][w]<MAX)
    103 {
    104 cout<<"顶点"<<vexs[v]<<"到顶点"<<vexs[w]<<"的最短路径长为"<<Dist[v][w]<<endl;
    105 cout<<"经过的顶点为:";
    106 j=w;
    107 c=0;
    108 while(path[v][j]!=-1)
    109 {
    110 a[c]=path[v][j];
    111 j=path[v][j];
    112 c++;
    113 }
    114 for(j=c-1;j>=0;j--)
    115 cout<<vexs[a[j]]<<"->";
    116 cout<<vexs[w]<<endl;
    117 }
    118 }
    119 };

      测试文件"main.cpp"

     1 #include"graph.h"
    2
    3 int main()
    4 {
    5 MGraph G;
    6 G.Create_MG();
    7
    8 int Dist[20][20];
    9 int path[20][20];
    10
    11 cout<<"求有向网中没两个顶点之间的最短路径"<<endl;
    12 G.Floyd_Short_Path(path,Dist);
    13 cout<<endl;
    14
    15 G.Print(path,Dist);
    16 cout<<endl;
    17
    18 return 0;
    19 }
    20

      下面是输入和输出结果:

     1 输入图的顶点数和边数:6 8
    2 输入各个顶点的民称:v1 v2 v3 v4 v5 v6
    3 输入每条边对应的始点和终点以及该边的权值:v1 v3 10
    4 输入每条边对应的始点和终点以及该边的权值:v1 v5 30
    5 输入每条边对应的始点和终点以及该边的权值:v1 v6 100
    6 输入每条边对应的始点和终点以及该边的权值:v2 v3 5
    7 输入每条边对应的始点和终点以及该边的权值:v3 v4 50
    8 输入每条边对应的始点和终点以及该边的权值:v5 v4 20
    9 输入每条边对应的始点和终点以及该边的权值:v4 v6 10
    10 输入每条边对应的始点和终点以及该边的权值:v5 v6 60
    11 图构造完成
    12 求有向网中没两个顶点之间的最短路径
    13
    14 ___输出每两个顶点之间的最短路径和经过的顶点___
    15 顶点v1到顶点v3的最短路径长为10
    16 经过的顶点为:v1->v3
    17 顶点v1到顶点v4的最短路径长为50
    18 经过的顶点为:v1->v5->v4
    19 顶点v1到顶点v5的最短路径长为30
    20 经过的顶点为:v1->v5
    21 顶点v1到顶点v6的最短路径长为60
    22 经过的顶点为:v1->v5->v4->v6
    23 顶点v2到顶点v3的最短路径长为5
    24 经过的顶点为:v2->v3
    25 顶点v2到顶点v4的最短路径长为55
    26 经过的顶点为:v2->v3->v4
    27 顶点v2到顶点v6的最短路径长为65
    28 经过的顶点为:v2->v3->v4->v6
    29 顶点v3到顶点v4的最短路径长为50
    30 经过的顶点为:v3->v4
    31 顶点v3到顶点v6的最短路径长为60
    32 经过的顶点为:v3->v4->v6
    33 顶点v4到顶点v6的最短路径长为10
    34 经过的顶点为:v4->v6
    35 顶点v5到顶点v4的最短路径长为20
    36 经过的顶点为:v5->v4
    37 顶点v5到顶点v6的最短路径长为30
    38 经过的顶点为:v5->v4->v6
    39
    40 Press any key to continue

      












  • 相关阅读:
    2016中国大学生程序设计竞赛
    HDU 1671 Phone List (Trie·数组实现)
    Codeforces Round #367 (Div. 2) Hard problem
    UVA 133 The Dole Queue
    SG函数模板
    Codeforces Round #366 (Div. 2) C Thor(模拟+2种stl)
    [Offer收割]编程练习赛4 A 满减优惠
    CF #365 (Div. 2) D
    Codeforces Round #365 (Div. 2) Chris and Road
    codeblocks AStyle修改格式和快捷键
  • 原文地址:https://www.cnblogs.com/math2010/p/2142063.html
Copyright © 2011-2022 走看看