Floyed

作者在 2008-05-11 10:41:50 发布以下内容
从有向图的带权的邻接矩阵 cost出发,对有向图的n个顶点加以编号,若从ij有弧(i=12...nj=12...n),则从ij 存在一条长度为cost(ij)的路线。但该路径不一定是最短路径,尚需修改,修改的方法是进行n次试探。首先考虑路径(i1j)(即在ij中插进点1),看〈i1〉,〈1j〉是否存在,若存在,再比较 ij)与(i1j)这两条路径,长度较短者为当前求得的最短路径。于是这条求得的最短路径的 中间点序号不大于1。然后再在各对点ij中插进一个点2,看〈i...2〉,〈2...j〉是否存在, 若不存在,那么当前的最短路径仍是上次求得的中间点序号不大于1的最短路径;若存在,则将 i...2j)的路径与前次求出的中间点序号不大于1的最短路径进行比较,取长度较短者 为当前的最短路径。这样,这次求得的最短路径的中间点序号不大于2......,依次类推,直至求得 ij的最短路径。

    Floyed的主程序段很精简,就是3重循环。

    for (k = 0; k < n; k ++)

              for (i = 0; i < n; i ++)

                     if (i != k) for (j = 0; j < n; j ++)

                            if ((j != i && j != k) && (map[i][k] + map[k][j] < map[i][j]))

                                   map[i][j] = map[i][k] + map[k][j];

参考程序

//读入顶点总数n,边总数m,和m行的边信息(此处为无向图)。

//输出从起点到其它所有点的最短路

//例如:

//5 9 (顶点数为5, 9条边)

//1 2 3    (第一条边的信息顶点1和顶点2相连,权值为3)

//1 5 30

//2 3 25

//2 4 8

//3 5 10

//4 1 20

//4 3 4

//4 5 12

//5 1 5

#include <stdio.h>
int map[201][201] = {0};
int path[201][201] = {0};
void write(int i , int j)     //递归输出路径
{
 if (path[i][j] > 0)
 {
  write(i , path[i][j]);
  write(path[i][j] , j);
 }
 else printf("-->%d" , j);
}
int main()
{
 int i , j , k , s , t , w , n , m;
 //读入数据
 scanf("%d %d" , &n , &m);
 for (i = 0; i < m; i ++)
 {
  scanf("%d %d %d" , &s , &t , &w);
  map[s][t] = w; map[t][s] = w;
 }
 //Floyed
 for (k = 1; k <= n; k ++)
  for (i = 1; i <= n; i ++)
   if (k != i)
    for (j = 1; j <= n; j ++)
     if ((j != i) && (j != k) && (map[i][k] > 0) && (map[k][j] > 0) &&((map[i][j] == 0) || (map[i][k] + map[k][j] < map[i][j])))
     {
      map[i][j] = map[i][k] + map[k][j];
      path[i][j] = k;
     }
     //此时map[i][j]表示i到j的最短路
     //输出路径和最短距离
     for (i = 1; i <= n; i ++)
      for (j = 1; j <= n; j ++)
       if (i != j)
       {
        printf("%d ==> %d : %d   %d" , i , j , map[i][j] , i);
        write(i , j);
        printf("\n");
       }
       getchar(); getchar();
       return 0;
}

算法 | 阅读 1890 次
文章评论,共0条
游客请输入验证码
最新评论