大學經典教材《資料結構》(C語言版 嚴蔚敏 吳為民 編著) 中該演算法的實現
阿新 • • 發佈:2018-12-18
/* 測試資料 教科書 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; }