最短路径:Dijkstra算法和Floyd算法

来源:互联网 发布:php tp框架邮箱验证码 编辑:程序博客网 时间:2024/06/10 01:31

      最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。算法具体的形式包括:

        1.确定起点的最短路径问题:即已知起始结点,求最短路径的问题。适合使用Dijkstra算法。

        2.确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。

        3.确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。

        4.全局最短路径问题:求图中所有的最短路径。适合使用Floyd算法。

        这里只给出第1种和第四种情况下两种算法的源代码。

[objc] view plain copy
  1. #include "stdio.h"  
  2. #define MAX 99  
  3.   
  4. typedef struct                    //图的邻接矩阵存储结构体定义  
  5. {  
  6.     int vexs[6];  
  7.     int arcs[6][6];  
  8.     int n, e;  
  9. }MGraph;  
  10.   
  11. void create(MGraph &G);                 //图的创建  
  12. void Dijkstra(MGraph G, int u);         //Dijkstra算法  
  13. void Floyd(MGraph G);                   //Floyd算法  
  14.   
  15. int main()  
  16. {  
  17.     MGraph G;  
  18.     create(G);  
  19.     printf("最短路径之Dijkstra算法:\n");  
  20.     Dijkstra(G, 0);  
  21.     printf("最短路径之Floyd算法:\n");  
  22.     Floyd(G);  
  23.   
  24.     return 0;  
  25. }  
  26.   
  27. void create(MGraph &G)  
  28. {  
  29.     int i, j;  
  30.     printf("请输入顶点数和边数:\n");  
  31.     scanf("%d %d", &G.n, &G.e);  
  32.   
  33.     int b[10] = {0123456789};  
  34.     for(i = 0; i < G.n; ++i)  
  35.         G.vexs[i] = b[i];  
  36.     printf("顶点编号分别为:\n");  
  37.     for(i = 0; i < G.n; ++i)  
  38.         printf("%d ", G.vexs[i]);  
  39.   
  40.     int a[6][6]={  
  41.         {03, MAX, MAX, MAX, MAX},  
  42.         {MAX, 02, MAX, 67},  
  43.         {MAX, MAX, 0134},   
  44.         {MAX, MAX, MAX, 01, MAX},  
  45.         {MAX, MAX, MAX, MAX, 01},   
  46.         {MAX, MAX, MAX, MAX, MAX, 0}  
  47.     };  
  48.     for(i = 0; i < 6; ++i)  
  49.         for(j = 0; j < 6; ++j)  
  50.               G.arcs[i][j]=a[i][j];  
  51.     printf("\n该图的邻接矩阵:\n");  
  52.     for(i = 0; i < G.n; ++i)  
  53.     {  
  54.         for(j = 0; j < G.n; ++j)  
  55.             printf("%d ", G.arcs[i][j]);  
  56.         printf("\n");  
  57.     }  
  58. }  
  59. //Dijkstra算法  
  60. void Dijkstra(MGraph G, int u)        //假设此处从顶点0开始  
  61. {  
  62.     int i, j, k, min;  
  63.     int pre[10], final[10], dist[10];  
  64.     for(j = 0; j < G.n; ++j)  
  65.     {  
  66.         dist[j] = G.arcs[u][j];  
  67.         if(G.arcs[u][j] == MAX)  
  68.             pre[j] = -1;  
  69.         else  
  70.             pre[j] = u;  
  71.         final[j] = 0;  
  72.     }  
  73.     for(i = 1; i < G.n; ++i)  
  74.     {  
  75.         min = MAX;  
  76.         for(j = 1; j < G.n; ++j)     //找出最小值的结点  
  77.             if( (!final[j]) && (min > dist[j]))  
  78.             {  
  79.                 min = dist[j];  
  80.                 k = j;  
  81.             }  
  82.         if(min == MAX)    //找不到  
  83.             break;  
  84.         final[k] = 1;   //加入该结点  
  85.         for(j = 1; j < G.n; ++j)  //更新最短路径  
  86.         {  
  87.             if((!final[j]) && (dist[j] > (dist[k] + G.arcs[k][j])))  
  88.             {  
  89.                 dist[j] = dist[k] + G.arcs[k][j];  
  90.                 pre[j] = k;  
  91.             }  
  92.         }  
  93.     }  
  94.     for(i = 1; i < G.n; ++i)       //输出路径与距离  
  95.     {  
  96.         if(pre[i] == -1)  
  97.         {  
  98.             printf("顶点%d到源点%d不可达。\n", i, u);  
  99.             continue;  
  100.         }  
  101.         printf("(%d, %d) = %d\n", i, u, dist[i]);  
  102.         printf("路径为:");  
  103.         j = i;  
  104.         while(j)  
  105.         {  
  106.             printf("%d→", j);  
  107.             j = pre[j];  
  108.         }  
  109.         printf("0\n");  
  110.     }  
  111. }  
  112. //Floyd算法  
  113. void Floyd(MGraph G)  
  114. {  
  115.     int i, j, k, dist[10][10], pre[10];  
  116.     for(i = 0; i < G.n; ++i)  
  117.         for(j = 0; j < G.n; ++j)  
  118.         {  
  119.             dist[i][j] = G.arcs[i][j];  
  120.             if(dist[i][j] != MAX)  
  121.                 pre[j] = i;  
  122.             else  
  123.                 pre[j] = -1;  
  124.         }  
  125.               
  126.     for(k = 0; k < G.n; ++k)  
  127.         for(i = 0; i < G.n; ++i)  
  128.             for(j = 0; j < G.n; ++j)  
  129.                 if((i != j) && (dist[i][j] > dist[i][k] + dist[k][j]))  
  130.                 {  
  131.                     dist[i][j] = dist[i][k] + dist[k][j];  
  132.                     if(dist[i][j] != MAX)  
  133.                     {  
  134.                         pre[j] = k;  
  135.                         pre[k] = i;  
  136.                     }  
  137.                     else  
  138.                         pre[j] = -1;  
  139.                 }  
  140.     for(i = 0; i < G.n; ++i)  
  141.         for(j = 0; j < G.n; ++j)  
  142.         {  
  143.             if(dist[i][j] == MAX)  
  144.                 continue;  
  145.             else if(i != j)  
  146.                 printf("(%d, %d) = %d\n", i, j, dist[i][j]);  
  147.         }  
  148.     printf("其余顶点之间不可达!\n");  
  149. }  

示例:(读者可自行验证)

0 0