【C/C++】Dijkstra算法的簡潔實現


 

 Dijkstra的實現有很多種,下面給出一種較為簡潔和高效的實現,可以作為模板快速使用。

  1. 使用鄰接表存儲圖;

  2. 使用標准STL的vector存儲每個點的所有鄰接邊;

  3. 使用pair記錄當前搜索的點,pair<int,int>對:

    first記錄最小距離,用以在優先隊列中實現類似'最小堆優化';

    second記錄該最小距離對應的點;

  4. 使用priority_queue實現優化;(附使用方法)

  5. 一個細節:這是盲目檢索,中途若D[i] < p.first,說明隊列里的該點已經到達了,這個pair已經無效,直接continue;

 

  實現:

 1 #include<bits/stdc++.h> 
 2 #define INF 100000005
 3 #define MAX 100006 
 4 using namespace std;
 5 
 6 typedef pair<int,int> P;
 7 
 8 struct edge{
 9     int to;
10     int cost;
11     edge(int t,int c):to(t),cost(c){
12     }
13 };
14 
15 const int N = 100006;
16 vector<edge> g[N];
17 int D[N]; //距離 
18 int n,m; //n個點 m條邊 
19 
20 void Dijkstra(int s){
21     priority_queue<P,vector<P>,greater<P> > que; //小端優先隊列 
22     fill(D,D+MAX,INF);//注意必須初始化為最大
23     D[s] = 0;
24     que.push(P(0,s));
25     while(!que.empty()){
26         P p = que.top();
27         que.pop();
28         int v = p.second;
29         if(D[v] < p.first) continue; //說明該點無需重復
30         for(int i = 0;i<g[v].size();i++) {
31             //遍歷所有后續邊 
32             edge e = g[v][i];
33             int to = e.to;
34             int cost = e.cost;
35             if(D[to] > D[v] + cost){
36                 D[to] = D[v] + cost;
37                 que.push(P(D[to],to));
38             }
39         }
40     }
41 }
42 
43 int main(){
44     cin>>n>>m;
45     int a,b,d;
46     //Vector<edge> g[MAX]的初始化
47     for(int i = 0;i<MAX;i++) {
48         g[i].clear();
49     }
50     //距離D的初始化
51     //fill(D,D+MAX,INF) ;//等Dijkstra時再初始化也行 
52     for(int i = 0;i<m;i++){
53         cin>>a>>b>>d;
54         g[a].push_back(edge(b,d));
55         g[b].push_back(edge(a,d));
56     }
57     int s,t;//起點 終點 
58     s = 1;
59     t = n;
60     Dijkstra(s);
61     cout<<D[n]<<endl;
62     return 0;
63 }

 

   【Appendix】

  priority_queue的使用方法:

  • 對於基本數據:
    •  priority_queue<int> q;
    •  priority_queue<int,vector<int>,less<int> > q; //默認,less可以省
    •  這創建的是‘大 ’優先隊列,大的在top
    •  取:q.top();
    •  出:q.pop();
    •  放:q.push(int);

 

  •  創建‘小 ’優先隊列:
    •  priority_queue<int,vector<int>,greater<int> > q;

 

  •  對於結構體數據:
    •  1. 結構體運算符重載

     bool operator < (const struct1,const struct1) const{
       return ?;
      }

    • 2. 定義cmp函數,做參數傳入,更加靈活

      bool cmp(struct1,struct2){
         return ?;
      }
      priority_queue<struct1,vector<struct2>,cmp> q;

  

 

 

 


免責聲明!

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



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