回顧算法思路:
該算法用於求指定頂點A到其余每個頂點的最短路徑;
將頂點分為兩部分S、U,S部分是已經確定最短路徑的點,另一部分U是尚未確定最短路徑的點,
確保目前狀態X的所有路徑是從集合S到U某一點的最短路徑(即路徑只有終點在U中,其余頂點均在S中;
1、在所有路徑中選取最短的路徑所對應的頂點加入到S中(該條路徑已經是確定的最短路徑;
2、由於S中加入了一個頂點B,更新其他路徑以達到狀態X
循環1、2,確保所有的點都已加入S,結束;
#include<iostream> #include<cstdlib> #include<string> using namespace std; struct Dis { string path;//存儲路徑 int value;//存儲路徑的值 bool visit;//是否加入S中 Dis() {//構造函數 visit = "false"; value = INT_MAX; path = ""; } }; struct Graph_DG { int vexnum;//頂點的數量 int arcnum;//邊的數量 int **a;//存儲圖即每對頂點的權重 Dis *dis; }; int main() { cout << "本算法計算的是從無向圖中一個指定點到其他任何一點"<< "的最短距離,以及對應的路徑" << endl; Graph_DG DG; /*創建圖*/ cout << "請輸入頂點數和邊數:"; cin >> DG.vexnum >> DG.arcnum; DG.a = new int *[DG.vexnum]; for (int i = 0; i < DG.vexnum; i++) { DG.a[i] = new int[DG.vexnum]; for (int j = 0; j < DG.vexnum; j++) { DG.a[i][j] = INT_MAX; if (i == j) DG.a[i][j] = 0; } } cout << "請輸入每條邊的起始點,終點和對應的權值" << endl; for (int i = 0; i < DG.arcnum; i++) { int x, y; cin >> x >> y; cin >> DG.a[x][y]; DG.a[y][x] = DG.a[x][y]; } int start; cout << "請輸入該指定點:"; cin >> start; DG.dis = new Dis[DG.vexnum]; for (int i = 0; i < DG.vexnum; i++) { DG.dis[i].value = DG.a[start][i]; DG.dis[i].visit = false; DG.dis[i].path = to_string(start) + "-->" + to_string(i); } //使用迪傑斯特拉算法 int count = 1; DG.dis[start].visit = true;//將起點加入S中 while (count < DG.vexnum) { int min = INT_MAX; int temp; for (int i = 0; i < DG.vexnum; i++) { if (DG.dis[i].value <= min && DG.dis[i].visit == false) {//只要有未加入的點,就找出距離最短的點加入 min = DG.dis[i].value; temp = i; } } count++; DG.dis[temp].visit = true; //更新距離 for (int i = 0; i < DG.vexnum ; i++) { if (DG.dis[i].visit == false) { if (DG.a[temp][i] < INT_MAX && DG.dis[i].value < INT_MAX && DG.dis[temp].value + DG.a[temp][i] < DG.dis[i].value) { DG.dis[i].path = DG.dis[temp].path + "-->" + to_string(i); DG.dis[i].value = DG.dis[temp].value + DG.a[temp][i]; } } } } //打印輸出 for (int i = 0; i < DG.vexnum; i++) { if(DG.dis[i].value < INT_MAX) cout <<"距離:"<< DG.dis[i].value <<"最短路徑:"<< " , "<< DG.dis[i].path << endl; else cout << "距離:" << "infinite , " << "最短路徑:" << DG.dis[i].path << endl; } //非內部數據類型手動釋放內存 delete[] DG.dis; //二維數組釋放內存的方法 for (int i = 0; i < DG.vexnum; i++) delete[] DG.a[i]; delete[] DG.a; system("pause"); return 0; }
運行結果如下: