关于Dijkstra算法的实现

来源:互联网 发布:.cc域名权重 编辑:程序博客网 时间:2024/05/18 22:45
[cpp] view plaincopyprint?
  1.  #include <iostream>   
  2. using namespace std;  
  3.    
  4. const int maxnum = 100;  
  5. const int maxint = 999999;  
  6.    
  7.    
  8. void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum])  
  9. {  
  10.     bool s[maxnum];    // 判断是否已存入该点到S集合中  
  11.     for(int i=1; i<=n; ++i)  
  12.     {  
  13.         dist[i] = c[v][i];  
  14.         s[i] = 0;     // 初始都未用过该点   
  15.         if(dist[i] == maxint)  
  16.             prev[i] = 0;  
  17.         else  
  18.             prev[i] = v;  
  19.     }  
  20.     dist[v] = 0;  
  21.     s[v] = 1;  
  22.    
  23.     // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中  
  24.     // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度  
  25.     for(int i=2; i<=n; ++i)  
  26.     {  
  27.         int tmp = maxint;  
  28.         int u = v;  
  29.         // 找出当前未使用的点j的dist[j]最小值  
  30.         for(int j=1; j<=n; ++j)  
  31.             if((!s[j]) && dist[j]<tmp)  
  32.             {  
  33.                 u = j;              // u保存当前邻接点中距离最小的点的号码  
  34.                 tmp = dist[j];  
  35.             }  
  36.         s[u] = 1;    // 表示u点已存入S集合中   
  37.    
  38.         // 更新dist   
  39.         for(int j=1; j<=n; ++j)  
  40.             if((!s[j]) && c[u][j]<maxint)  
  41.             {  
  42.                 int newdist = dist[u] + c[u][j];  
  43.                 if(newdist < dist[j])  
  44.                 {  
  45.                     dist[j] = newdist;  
  46.                     prev[j] = u;  
  47.                 }  
  48.             }  
  49.     }  
  50. }  
  51.    
  52. void searchPath(int *prev,int v, int u)  
  53. {  
  54.     int que[maxnum];  
  55.     int tot = 1;  
  56.     que[tot] = u;  
  57.     tot++;  
  58.     int tmp = prev[u];  
  59.     while(tmp != v)  
  60.     {  
  61.         que[tot] = tmp;  
  62.         tot++;  
  63.         tmp = prev[tmp];  
  64.     }  
  65.     que[tot] = v;  
  66.     for(int i=tot; i>=1; --i)  
  67.         if(i != 1)  
  68.             cout << que[i] << " -> ";  
  69.         else  
  70.             cout << que[i] << endl;  
  71. }  
  72.    
  73. int main()  
  74. {  
  75.     freopen("input.txt""r", stdin);  
  76.     // 各数组都从下标1开始   
  77.     int dist[maxnum];     // 表示当前点到源点的最短路径长度  
  78.     int prev[maxnum];     // 记录当前点的前一个结点  
  79.     int c[maxnum][maxnum];   // 记录图的两点间路径长度  
  80.     int n, line;             // 图的结点数和路径数  
  81.    
  82.     // 输入结点数   
  83.     cin >> n;  
  84.     // 输入路径数   
  85.     cin >> line;  
  86.     int p, q, len;          // 输入p, q两点及其路径长度  
  87.    
  88.     // 初始化c[][]为maxint   
  89.     for(int i=1; i<=n; ++i)  
  90.         for(int j=1; j<=n; ++j)  
  91.             c[i][j] = maxint;  
  92.    
  93.     for(int i=1; i<=line; ++i)    
  94.     {  
  95.         cin >> p >> q >> len;  
  96.         if(len < c[p][q])       // 有重边  
  97.         {  
  98.             c[p][q] = len;      // p指向q   
  99.             c[q][p] = len;      // q指向p,这样表示无向图  
  100.         }  
  101.     }  
  102.    
  103.     for(int i=1; i<=n; ++i)  
  104.         dist[i] = maxint;  
  105.     for(int i=1; i<=n; ++i)  
  106.     {  
  107.         for(int j=1; j<=n; ++j)  
  108.             printf("%8d", c[i][j]);  
  109.         printf("\n");  
  110.     }  
  111.    
  112.     Dijkstra(n, 1, dist, prev, c);  
  113.    
  114.     // 最短路径长度   
  115.     cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;  
  116.    
  117.     // 路径   
  118.     cout << "源点到最后一个顶点的路径为: ";  
  119.     searchPath(prev, 1, n);  
  120. }  
  121.   
  122. 输入数据:  
  123. 5  
  124. 7  
  125. 1 2 10  
  126. 1 4 30  
  127. 1 5 100  
  128. 2 3 50  
  129. 3 5 10  
  130. 4 3 20  
  131. 4 5 60  

 

 Dijkstra 图如下所示:


 result is:

 

原创粉丝点击