如下圖,使用迪傑斯特拉算法求下圖的最短路徑
跌代過程:
1) 初始時從1開始尋找各節點到該節點的距離,路不通設置為maxint,此時把1歸為s里面
2)從1)得到距離1最短的路徑對應的結點如上圖為2,並把2歸到s里面並求各節點(剩下的不在s里面的)到2的距離,如果新的距離更小的話則更新dist[i]
3) 從2)得到距離2最短的路徑對應的結點如上圖為4,並把4歸到s里面並求各節點(剩下的不在s里面的)到4的距離,如果新的距離更小的話則更新dist[i]
4)依次類推可以把算有的節點遍歷,並且最終的dist[i]便是從初始節點1到i的最短路徑
算法如下
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int main() 6 { 7 cout << "請輸入圖的頂點數" << endl; 8 int n; 9 cin >> n; 10 int Amap[n+1][n+1]; 11 for(int i=1;i<=n;i++){//初始化map 12 for(int j=1;j<=n;j++){ 13 Amap[i][j]=99999; 14 } 15 } 16 cout << " 請輸入圖的邊數" << endl; 17 int m; 18 cin >> m; 19 cout << " 請輸入圖的邊的起點和終點和邊的長度" << endl; 20 int t1=0; 21 int t2=0; 22 int t3=0; 23 for(int j=0;j<m;j++){//更改t1到t2的長度 24 cin >> t1 >> t2 >> t3; 25 Amap[t1][t2]=t3; 26 } 27 int foot[n+1];//記錄頂點是否歸到已確定的路徑里面 28 memset(foot,0,sizeof(foot)); 29 foot[1]=1;//默認從1開始 30 int dist[n+1];//記錄每個頂點所對應的最短特殊路徑 31 for(int i=1;i<=n;i++){ 32 dist[i]=Amap[1][i];//初始化第一個頂點的dist數組 33 } 34 int as[n];//用來記錄經過的頂點順序 35 memset(as,0,sizeof(as)); 36 as[0]=1;//默認從一開始 37 int u; 38 for(int i=1;i<=n-1;i++){ 39 int min=99999; 40 for(int j=1;j<=n;j++){//獲取到該頂點的最短路徑對應的下一個頂點的位置u 41 if(foot[j]==0 && dist[j]< min){ 42 min=dist[j]; 43 u=j; 44 } 45 } 46 foot[u]=1;//設置為一,表示已經選取 47 as[i]=u;//記錄下來該頂點 48 for(int k=1;k<=n;k++){//更新當前的dist數組 49 if(Amap[u][k]<99999){//表示頂點之間有路徑 50 if(dist[k]>dist[u]+Amap[u][k]){//當前該頂點的dist不是最短的則更新 51 dist[k] =dist[u] + Amap[u][k]; 52 } 53 } 54 } 55 56 } 57 cout << " 最短路徑經過的頂點為"<<endl; 58 for(int i=0;i<n;i++){ 59 cout << as[i] << " "; 60 } 61 cout << endl; 62 cout << "從一到各個頂點的長度為" << endl; 63 for(int i=1;i<=n;i++){ 64 if(dist[i]==99999){ 65 cout <<"從1到"<<i<< "的長度為"<<"-" << endl; 66 continue; 67 } 68 cout <<"從1到"<<i<< "的長度為"<<dist[i] << endl; 69 } 70 return 0; 71 }
運行結果截圖為
上述的代碼並沒有把從1到其它點的具體路徑記錄下來,下面是對上面的代碼的升級,實現了路徑的記錄。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int main() 6 { 7 //freopen("D:/Data1.txt","r",stdin); 8 cout << "請輸入圖的頂點數" << endl; 9 int n; 10 cin >> n; 11 int road[n+1][n+1][n+1];//用來記錄路徑; 12 memset(road,0,sizeof(road)); 13 14 int Amap[n+1][n+1]; 15 for(int i=1;i<=n;i++){//初始化map 16 for(int j=1;j<=n;j++){ 17 Amap[i][j]=99999; 18 } 19 } 20 cout << " 請輸入圖的邊數" << endl; 21 int m; 22 cin >> m; 23 cout << " 請輸入圖的邊的起點和終點和邊的長度" << endl; 24 int t1=0; 25 int t2=0; 26 int t3=0; 27 for(int j=0;j<m;j++){//更改t1到t2的長度 28 cin >> t1 >> t2 >> t3; 29 Amap[t1][t2]=t3; 30 } 31 for(int i=1;i<=1;i++){//初始化路線 32 for(int j=1;j<=n;j++){ 33 for(int k=1;k<=2;k++){ 34 if(k==1){ 35 road[i][j][k]=1; 36 } 37 if(Amap[i][j]!=99999&&k==2){ 38 road[i][j][k]=j; 39 } 40 } 41 } 42 } 43 int foot[n+1];//記錄頂點是否歸到已確定的路徑里面 44 memset(foot,0,sizeof(foot)); 45 foot[1]=1;//默認從1開始 46 int dist[n+1];//記錄每個頂點所對應的最短特殊路徑 47 for(int i=1;i<=n;i++){ 48 dist[i]=Amap[1][i];//初始化第一個頂點的dist數組 49 } 50 int as[n];//用來記錄經過的頂點順序 51 memset(as,0,sizeof(as)); 52 as[0]=1;//默認從一開始 53 int u; 54 for(int i=1;i<=n-1;i++){ 55 int min=99999; 56 for(int j=1;j<=n;j++){//獲取到該頂點的最短路徑對應的下一個頂點的位置u 57 if(foot[j]==0 && dist[j]< min){ 58 min=dist[j]; 59 u=j; 60 } 61 } 62 foot[u]=1;//設置為一,表示已經選取 63 as[i]=u;//記錄下來該頂點 64 for(int k=1;k<=n;k++){//更新當前的dist數組 65 if(Amap[u][k]<99999&&foot[k]==0){//表示頂點之間有路徑 66 if(dist[k]>dist[u]+Amap[u][k]){//當前該頂點的dist不是最短的則更新 67 dist[k] =dist[u] + Amap[u][k]; 68 for(int i1=1;i1<=n;i1++){//新的路徑比原來的路徑更短時更新並記錄這個新的路徑 69 if(road[1][u][i1]!=0){ 70 road[1][k][i1]=road[1][u][i1]; 71 } 72 else{ 73 road[1][k][i1]=k; 74 break; 75 } 76 } 77 } 78 } 79 } 80 81 } 82 cout << " 最短路徑經過的頂點為"<<endl; 83 for(int i=0;i<n;i++){ 84 cout << as[i] << " "; 85 } 86 cout << endl; 87 cout << "從一到各個頂點的長度為" << endl; 88 for(int i=1;i<=n;i++){ 89 if(dist[i]==99999){ 90 cout <<"從1到"<<i<< "的長度為"<<"-" << endl; 91 continue; 92 } 93 cout <<"從1到"<<i<< "的長度為"<<dist[i] << endl; 94 cout <<"從1到"<<i<< "的路徑為:"; 95 for(int i1=1;i1<=n;i1++){ 96 if(road[1][i][i1]!=0){ 97 cout << road[1][i][i1] <<"-->"; 98 } 99 } 100 cout << "end" << endl; 101 } 102 return 0; 103 }