算法导论学习笔记(19)——每对顶点间的最短路径(基于Floyd_Warshall算法)

Floyd-Warshall算法的运行时间为Θ(V3),它同样允许存在负权边,但假设不存在负权回路。该算法考虑的最优子结构与上述描述类似,即最短路径的子路径是最短路径。但是,它对中间路径的范围加以限制,使其增长与最短路径的最大边数的增长同步。令dij(k)=为从顶点i到顶点j、且满足所有中间顶点属于集合{1,2,…,k}的一条最短路径的权值,定义递归解:如果k=0,dij(k)=wij;如果k≥1,dij(k)=min{ dij(k-1), dik(k-1)+ dkj(k-1)}。可以想象,当k=1时,i到j的最短路径或者由边(i,j)构成,或者由边(i,1)、(1,j)构成。当k=2时,i到j的最短路径可能由子路径i到2和子路径2到j构成,而子路径2到j又可能由边(2,1)、(1,j)构成,即k=2的解包含了k=1的解。以此类推,当k=n时,即可得到每对顶点间最短路径的权值。

为了构造最短路径,定义πij(k)为从i出发的一条最短路径上顶点j的前趋,而这条路径上的中间顶点属于集合{1,2,…,k}。定义πij(k)的递归公式,对于k=0,如果i=j或wij=∞,πij(0) =NIT(-1);如果i≠j和wij<∞,πij(0) =i。对于k≥1,如果dij(k-1)≤dik(k-1)+ dkj(k-1),πij(k)ij(k-1);如果dij(k-1)>dik(k-1)+ dkj(k-1),πij(k)kj(k-1)

完整的实现代码如下:

完整的实现代码如下:

  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.     int A[MaxVertexNum][MaxVertexNum],path[MaxVertexNum][MaxVertexNum]; 
  46.     int i,j,k; 
  47.     for (i=0;i<G.n;i++) 
  48.     { 
  49.         for (j=0;j<G.n;j++) 
  50.         { 
  51.             A[i][j]=G.edges[i][j]; 
  52.             path[i][j]=-1; 
  53.         } 
  54.     } 
  55.     for (k=0;k<G.n;k++) 
  56.     { 
  57.         for (i=0;i<G.n;i++) 
  58.         { 
  59.             for (j=0;j<G.n;j++) 
  60.             { 
  61.                 if (A[i][j]>A[i][k]+A[k][j]) 
  62.                 { 
  63.                     A[i][j]=A[i][k]+A[k][j]; 
  64.                     path[i][j]=k; 
  65.                 } 
  66.             } 
  67.         } 
  68.     } 
  69.     Dispath(A,path,G.n); 
  70.  
  71. void Ppath(int path[][MaxVertexNum],int i,int j) 
  72.     int k; 
  73.     k=path[i][j]; 
  74.     if (k==-1) 
  75.     { 
  76.         return
  77.     } 
  78.     Ppath(path,i,k); 
  79.     printf("%d",k); 
  80.     Ppath(path,k,j); 
  81.  
  82. void Dispath(int A[][MaxVertexNum],int path[][MaxVertexNum],int n) 
  83.     int i,j; 
  84.     for (i=0;i<n;i++) 
  85.     { 
  86.         for (j=0;j<n;j++) 
  87.         { 
  88.             if (A[i][j]==INF) 
  89.             { 
  90.                 if (i!=j) 
  91.                 { 
  92.                     printf("从%d到%d没有路径/n",i,j); 
  93.                 } 
  94.             } 
  95.             else 
  96.             { 
  97.                 printf("  从%d到%d=>路径长度:%d路径:",i,j,A[i][j]); 
  98.                 printf("%d,",i); 
  99.                 Ppath(path,i,j); 
  100.                 printf("%d/n",j); 
  101.             } 
  102.         } 
  103.     } 
  104.  
  105. int main() 
  106.     MGraph G; 
  107.     CreateMGraph(G); 
  108.     Floyd(G); 
  109.     return 0; 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值