zoukankan      html  css  js  c++  java
  • floyd 算法的个人理解

    在做过hdu 1358之后,若菜对floyd也有了更深的理解,学过数据结构的都知道,floyd是用于求每一对顶点之间的最短距离(当然你也可以用dijkstra来求,只不过floyd形式更简单)。。。好吧,先说说我的理解吧,其实floyd本质上还是dp,如果要求顶点vi到顶点vj的距离,那么,我们可以在vi,vj之间引入一个最大点vk,通过vk求出vi到vj的距离的最小值,当然1<=vk<=n(假设有n个顶点),然后更新就行了。。。。然后就是路径的保存了,一般用path[i][j]来保存vi到vj的路径的上到达顶点vj的前一个点。。。然后我在做1538这道题的时候,突然发现其实我们也可以用path[i][j]来保存顶点vi到vj路径上的vi的后一个顶点。。。

    好吧,下面的测试数据来自hdu 1538上的数据。。。其实我是自己懒得造数据。。。

    View Code
     1 #include<iostream>
     2 const int N=100;
     3 const int inf=100000000;
     4 using namespace std;
     5 
     6 int cost[N];
     7 int edge[N][N];
     8 int path[N][N];
     9 int n,v0,v;
    10 
    11 //逆序输出
    12 void floyd1(){
    13     for(int k=1;k<=n;k++){
    14         for(int i=1;i<=n;i++){
    15             for(int j=1;j<=n;j++){
    16                 if(cost[k]+edge[i][k]+edge[k][j]<edge[i][j]){
    17                     edge[i][j]=edge[i][k]+edge[k][j]+cost[k];
    18                     path[i][j]=path[k][j];//这个与初始化对应,此时path保存的就是vi->vj路径上的vj的前一个顶点
    19                 }
    20             }
    21         }
    22     }
    23     int k=v;
    24     printf("%d ",k);
    25     while(path[v0][k]!=v0){
    26         k=path[v0][k];
    27         printf("%d ",k);
    28     }
    29     printf("%d\n",path[v0][k]);
    30 }
    31 //顺序输出
    32 void floyd2(){
    33     for(int k=1;k<=n;k++){
    34         for(int i=1;i<=n;i++){
    35             for(int j=1;j<=n;j++){
    36                 if(cost[k]+edge[i][k]+edge[k][j]<edge[i][j]){
    37                     edge[i][j]=edge[i][k]+edge[k][j]+cost[k];
    38                     path[i][j]=path[i][k];//此时path保存的是vi->vj的路径上的起点
    39                 }
    40             }
    41         }
    42     }
    43     int k=v0;
    44     printf("%d ",k);
    45     while(path[k][v]!=v){
    46         k=path[k][v];
    47         printf("%d ",k);
    48     }
    49     printf("%d\n",path[k][v]);
    50 }
    51 
    52 int main(){
    53     while(scanf("%d",&n)!=EOF){
    54         for(int i=1;i<=n;i++){
    55             for(int j=1;j<=n;j++){
    56                 scanf("%d",&edge[i][j]);
    57                 //path[i][j]=i;//如果初始化为i的话,如果想要保存路径,后面更新的时候,必须用path[i][j]=path[k][j];此时path保存的即为逆序
    58                 path[i][j]=j;
    59                 if(edge[i][j]==-1){
    60                     edge[i][j]=inf;
    61                 }
    62             }
    63         }
    64         for(int i=1;i<=n;i++){
    65             scanf("%d",&cost[i]);
    66         }
    67         while(scanf("%d%d",&v0,&v)==2){
    68             if(v0==-1&&v==-1)break;
    69         //    floyd1();
    70             floyd2();
    71         }
    72     }
    73     return 0;
    74 }

    好吧,我好好的想了一下,确实也是,由于path是二维数组,似乎有两种选择也不为怪吧。。。

    orz,以后就直接顺序输出路径了,逆序还得用一个数组来保存,麻烦。。。。

  • 相关阅读:
    使用Spring的ReloadableResourceBundleMessageSource读取properties配置
    IFrame自适应高度
    Js返回页面顶部
    复制页面内容时添加额外信息
    怎样将Excel中的日期格式转换为文本格式
    为Tomcat页面设置访问权限(HTTP)
    为tomcat页面设置访问权限(BASIC认证)
    离线安装Maven FOR Eclipse插件
    sharepoint 获得上级和部门的封装函数
    SharePoint定制开发个性皮肤
  • 原文地址:https://www.cnblogs.com/wally/p/2882277.html
Copyright © 2011-2022 走看看