动态规划-2-所有结点对最短路径

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define VERTEX    5
  5 #define INF    99999
  6 #define NIL -1
  7 
  8 void print_all_pairs_shortest_path(int pi[][VERTEX], int i, int j)
  9 {
 10     if (i == j)
 11         printf("%d, ", i);
 12     else if (pi[i][j] == NIL)
 13         printf("no path from %d to %d exists\n", i, j);
 14     else {
 15         print_all_pairs_shortest_path(pi, i, pi[i][j]);
 16         printf("%d, ", j);
 17     }
 18 }
 19 
 20 void print_matrix(int W[][VERTEX])
 21 {
 22     int i, j;
 23     for (i = 0; i < VERTEX; i++)
 24         for (j = 0; j < VERTEX; j++) {
 25             if (j == 0)
 26                 printf("\n");
 27             printf("%d\t", W[i][j]);
 28         }
 29     putchar('\n');
 30     printf("========================================\n");
 31 }
 32 
 33 
 34 /*
 35 结点编号:从 0 到 VERTEX-1
 36 
 37 
 38 */
 39 void floyd_warshall(int W[][VERTEX], int pi[][VERTEX])
 40 {
 41     int n = VERTEX;
 42     int k, i, j;
 43     /*
 44     loop invariant:
 45     结点编号i到编号j的
 46     中间节点编号小于k的最短路径
 47     存储在W[i][j]中
 48 
 49     初始化k为0,所以中间结点小于0的最短路径,即没有中间结点的最短路径,即边的权重或INF存储在W中
 50     */
 51     for (k = 0; k < VERTEX; k++) {
 52         for (i = 0; i < VERTEX; i++) {
 53             for (j = 0; j < VERTEX; j++) {
 54                 /*
 55                 用宏模拟无穷大时,可能出现错误的最短路径更新
 56                 因为理论上无穷大加负数也是无穷大,但符号常量加负数小于符号常量,导致错误更新
 57                 添加更新最短路的条件 W[i][k] != INF && W[k][j] != INF,避免错误发生
 58                 */
 59                 if (W[i][j] > W[i][k]+W[k][j] && W[i][k] != INF && W[k][j] != INF) {
 60                     W[i][j] = W[i][k]+W[k][j];
 61                     pi[i][j] = pi[k][j];
 62                 }
 63             }
 64         }
 65         printf("k = %d\n", k);
 66         print_matrix(W);
 67         print_matrix(pi);    
 68     }
 69 }
 70 
 71 int main()
 72 {
 73     int W[VERTEX][VERTEX] = {
 74         {0, 3, 8, INF, -4},
 75         {INF, 0, INF, 1, 7},
 76         {INF, 4, 0, INF, INF},
 77         {2, INF, -5, 0, INF},
 78         {INF, INF, INF, 6, 0}
 79     };
 80 
 81     int pi[VERTEX][VERTEX] = {
 82         {NIL, 0, 0, NIL, 0}, 
 83         {NIL, NIL, NIL, 1, 1}, 
 84         {NIL, 2, NIL, NIL, NIL},
 85         {3, NIL, 3, NIL, NIL},
 86         {NIL, NIL, NIL, 4, NIL}
 87     };
 88     print_matrix(W);
 89     print_matrix(pi);
 90     printf("========================================\n");
 91     floyd_warshall(W, pi);
 92     printf("========================================\n");
 93     int i, j;
 94     for (i = 0; i < VERTEX; i++)
 95         for (j = 0; j < VERTEX; j++) {
 96             printf("the shortest path from %d to %d is: ", i, j);
 97             print_all_pairs_shortest_path(pi, i, j);
 98             putchar('\n');
 99         }
100     return 0;
101 }

 

posted @ 2021-10-28 21:11  corsican  阅读(78)  评论(0)    收藏  举报