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,以后就直接顺序输出路径了,逆序还得用一个数组来保存,麻烦。。。。

posted @ 2013-01-30 00:01  ihge2k  阅读(697)  评论(0编辑  收藏  举报