1. 程式人生 > >大學經典教材《資料結構》(C語言版 嚴蔚敏 吳為民 編著) 中該演算法的實現

大學經典教材《資料結構》(C語言版 嚴蔚敏 吳為民 編著) 中該演算法的實現

/*
測試資料 教科書 P189 G6 的鄰接矩陣 其中 數字 1000000 代表無窮大
6
1000000 1000000 10 100000 30 100
1000000 1000000 5 1000000 1000000 1000000
1000000 1000000 1000000 50 1000000 1000000
1000000 1000000 1000000 1000000 1000000 10
1000000 1000000 1000000 20 1000000 60
1000000 1000000 1000000 1000000 1000000 1000000
結果:
D[0]   D[1]   D[2]   D[3]   D[4]   D[5]
 0   1000000   10     50     30     60
*/
#include <iostream>
#include <cstdio>
#define MAX 1000000
using namespace std;
int arcs[10][10];//鄰接矩陣
int D[10];//儲存最短路徑長度
int p[10][10];//路徑
int final[10];//若final[i] = 1則說明 頂點vi已在集合S中
int n = 0;//頂點個數
int v0 = 0;//源點
int v,w;
void ShortestPath_DIJ()
{
     for (v = 0; v < n; v++) //迴圈 初始化
     {
          final[v] = 0; D[v] = arcs[v0][v];
          for (w = 0; w < n; w++) p[v][w] = 0;//設空路徑
          if (D[v] < MAX) {p[v][v0] = 1; p[v][v] = 1;}
     }
     D[v0] = 0; final[v0]=0; //初始化 v0頂點屬於集合S
     //開始主迴圈 每次求得v0到某個頂點v的最短路徑 並加v到集合S中
     for (int i = 1; i < n; i++)
     {
          int min = MAX;
          for (w = 0; w < n; w++)
          {
               //我認為的核心過程--選點
               if (!final[w]) //如果w頂點在V-S中
               {
                    //這個過程最終選出的點 應該是選出當前V-S中與S有關聯邊
                    //且權值最小的頂點 書上描述為 當前離V0最近的點
                    if (D[w] < min) {v = w; min = D[w];}
               }
          }
          final[v] = 1; //選出該點後加入到合集S中
          for (w = 0; w < n; w++)//更新當前最短路徑和距離
          {
               /*在此迴圈中 v為當前剛選入集合S中的點
               則以點V為中間點 考察 d0v+dvw 是否小於 D[w] 如果小於 則更新
               比如加進點 3 則若要考察 D[5] 是否要更新 就 判斷 d(v0-v3) + d(v3-v5) 的和是否小於D[5]
               */
               if (!final[w] && (min+arcs[v][w]<D[w]))
               {
                    D[w] = min + arcs[v][w];
                   // p[w] = p[v];
                    p[w][w] = 1; //p[w] = p[v] + [w]
               }
          }
     }
}
 
 
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
         for (int j = 0; j < n; j++)
         {
              cin >> arcs[i][j];
         }
    }
    ShortestPath_DIJ();
    for (int i = 0; i < n; i++) printf("D[%d] = %d\n",i,D[i]);
    return 0;
}