每对顶点间最短路径----Floyd算法 收藏

每对顶点间最短路径----Floyd算法 收藏

 对于一个各边权值均大于零的有向图,对每一对顶点,求出vi与vj之间的最短路径和最短路径长度。

以下代码包含有向图的建立,Floyd算法的实现以及输出最短路径和最短路径长度,具体过程请看【动画演示Floyd算法】。

代码说明几点:

1、A[][]数组初始化为各顶点间的原本距离,最后存储各顶点间的最短距离。

2、path[][]数组保存最短路径,与当前迭代的次数有关。初始化都为-1,表示没有中间顶点。在求A[i][j]过程中,path[i][j]存放从顶点vi到顶点vj的中间顶点编号不大于k的最短路径上前一个结点的编号。在算法结束时,由二维数组path的值回溯,可以得到从顶点vi到顶点vj的最短路径。

初始化A[][]数组为如下,即有向图的邻接矩阵。

完整的实现代码如下:

 

  1. #include <iostream>  
  2. #include <string>     
  3. #include <stdio.h>     
  4. using namespace std;     
  5. #define MaxVertexNum 100     
  6. #define INF 32767     
  7. typedef struct    
  8. {     
  9.     char vertex[MaxVertexNum];     
  10.     int edges[MaxVertexNum][MaxVertexNum];     
  11.     int n,e;     
  12. }MGraph;     
  13.   
  14. void CreateMGraph(MGraph &G)     
  15. {     
  16.     int i,j,k,p;     
  17.     cout<<"请输入顶点数和边数:";     
  18.     cin>>G.n>>G.e;     
  19.     cout<<"请输入顶点元素:";     
  20.     for (i=0;i<G.n;i++)     
  21.     {     
  22.         cin>>G.vertex[i];     
  23.     }     
  24.     for (i=0;i<G.n;i++)     
  25.     {     
  26.         for (j=0;j<G.n;j++)     
  27.         {     
  28.             G.edges[i][j]=INF;     
  29.             if (i==j)     
  30.             {     
  31.                 G.edges[i][j]=0;     
  32.             }     
  33.         }     
  34.     }        
  35.     for (k=0;k<G.e;k++)     
  36.     {     
  37.         cout<<"请输入第"<<k+1<<"条弧头弧尾序号和相应的权值:";     
  38.         cin>>i>>j>>p;     
  39.         G.edges[i][j]=p;     
  40.     }     
  41. }     
  42. void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n);  
  43.   
  44. void Floyd(MGraph G)  
  45. {  
  46.     int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum];  
  47.     int i,j,k;  
  48.     for (i=0;i<G.n;i++)  
  49.     {  
  50.         for (j=0;j<G.n;j++)  
  51.         {  
  52.             A[i][j]=G.edges[i][j];  
  53.             path[i][j]=-1;  
  54.         }  
  55.     }  
  56.     for (k=0;k<G.n;k++)  
  57.     {  
  58.         for (i=0;i<G.n;i++)  
  59.         {  
  60.             for (j=0;j<G.n;j++)  
  61.             {  
  62.                 if (A[i][j]>A[i][k]+A[k][j])  
  63.                 {  
  64.                     A[i][j]=A[i][k]+A[k][j];  
  65.                     path[i][j]=k;  
  66.                 }  
  67.             }  
  68.         }  
  69.     }  
  70.     Dispath(A,path,G.n);  
  71. }  
  72.   
  73. void Ppath(int path[][MaxVertexNum],int i,int j)  
  74. {  
  75.     int k;  
  76.     k=path[i][j];  
  77.     if (k==-1)  
  78.     {  
  79.         return;  
  80.     }  
  81.     Ppath(path,i,k);  
  82.     printf("%d",k);  
  83.     Ppath(path,k,j);  
  84. }  
  85.   
  86. void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n)  
  87. {  
  88.     int i,j;  
  89.     for (i=0;i<n;i++)  
  90.     {  
  91.         for (j=0;j<n;j++)  
  92.         {  
  93.             if (A[i][j]==INF)  
  94.             {  
  95.                 if (i!=j)  
  96.                 {  
  97.                     printf("从%d到%d没有路径/n",i,j);  
  98.                 }  
  99.             }  
  100.             else  
  101.             {  
  102.                 printf("  从%d到%d=>路径长度:%d路径:",i,j,A[i][j]);  
  103.                 printf("%d,",i);  
  104.                 Ppath(path,i,j);  
  105.                 printf("%d/n",j);  
  106.             }  
  107.         }  
  108.     }  
  109. }  
  110.   
  111. int main()  
  112. {  
  113.     MGraph G;  
  114.     CreateMGraph(G);  
  115.     Floyd(G);  
  116.     return 0;  
  117. }  

 

测试结果如下:

结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值