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;