Floyd算法

  Dijkstra算法是解决单源最短路径的问题,就是某个点到其余各个点的最短路径,Floyd算法是解决任意两点间最短路径问题的。

  算法的大致流程如下:

  设置两个二维矩阵A和path,A记录任意两个顶点最短路径长度,path记录当前两顶点最短路径上要经过的中间节点。

  n个顶点,从0到n-1,每次以i为中间节点进行检测,检测所有顶点对(j,k),如果A[j][k]>A[j][i]+A[i][j],则令A[j][k]=A[j][i]+A[i][j],令path[j][k]=i

  依次检测完所有0~n-1的顶点,算法结束。最终的结果存储在A和path矩阵中。

  1 #include<cstdio>
  2 #define MAXSIZE 100
  3 #define INF 99999
  4 int A[MAXSIZE][MAXSIZE];
  5 int G[MAXSIZE][MAXSIZE];
  6 int path[MAXSIZE][MAXSIZE];
  7 void init(int n)
  8 {
  9     for(int i=0; i<n; ++i)
 10     {
 11         for(int j=0; j<n; ++j)
 12         {
 13             path[i][j]=-1;
 14             if(i==j)
 15                 G[i][j]=A[i][j]=0;
 16             else
 17                 G[i][j]=A[i][j]=INF;
 18         }
 19     }
 20 }
 21 void create(int e)
 22 {
 23     int a,b,val;
 24     for(int i=0; i<e; ++i)
 25     {
 26         scanf("%d%d%d",&a,&b,&val);
 27         A[a][b]=val;
 28         G[a][b]=val;
 29     }
 30     for(int i=0; i<4; ++i)
 31     {
 32         for(int j=0; j<4; ++j)
 33         {
 34             printf("%d\t",G[i][j]);
 35         }
 36         printf("\n");
 37     }
 38     printf("*******************************\n");
 39 }
 40 void Floyd(int n)
 41 {
 42     for(int i=0; i<n; ++i)
 43     {
 44         for(int j=0; j<n; ++j)
 45         {
 46             for(int k=0; k<n; ++k)
 47             {
 48                 if(j==k)
 49                     continue;
 50                 if(A[j][k]>A[j][i]+A[i][k])
 51                 {
 52                     A[j][k]=A[j][i]+A[i][k];
 53                     path[j][k]=i;
 54                 }
 55             }
 56         }
 57     }
 58 }
 59 void print(int n)
 60 {
 61     for(int i=0; i<n; ++i)
 62     {
 63         for(int j=0; j<n; ++j)
 64         {
 65             printf("%d\t",A[i][j]);
 66         }
 67         printf("\n");
 68     }
 69     printf("*******************************\n");
 70     for(int i=0; i<n; ++i)
 71     {
 72         for(int j=0; j<n; ++j)
 73         {
 74             printf("%d\t",path[i][j]);
 75         }
 76         printf("\n");
 77     }
 78 }
 79 void printPath(int u,int v)
 80 {
 81     if(path[u][v]==-1)
 82         printf("%d->",u);
 83     else
 84     {
 85         int mid = path[u][v];
 86         printPath(u,mid);
 87         printPath(mid,v);
 88     }
 89 }
 90 int main()
 91 {
 92     int n,e;
 93     scanf("%d%d",&n,&e);
 94     init(n);
 95     create(e);
 96     Floyd(n);
 97     print(n);
 98     int u,v;
 99     scanf("%d%d",&u,&v);
100     printPath(u,v);
101     printf("%d",v);
102     return 0;
103 }

 

  算法的时间复杂度为O(n3)。

 

      

  例如,我们以上图所示的图进行计算,第一部分为图的邻接矩阵,第二部分为求得的A,第三部分为求得的path。

  我们要求1到0的最短路径。

  1. path[1][0]=3,所以从1到0最短路要经过3,以3为起点
  2. path[3][0]=2,所以从3到1最短路要经过2,以2为起点
  3. path[2][0]=-1,所以,从顶点2有直接到0的边,结束

所以求最短路要用到递归,分别处理前后两段路径。

posted @ 2015-10-24 16:21  康小武  阅读(205)  评论(0编辑  收藏  举报