實現迪傑斯特拉算法


如下圖,使用迪傑斯特拉算法求下圖的最短路徑

 

跌代過程:

  

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM