【C/C++】Dijkstra算法的简洁实现

 

 Dijkstra的实现有不少种,下面给出一种较为简洁和高效的实现,能够做为模板快速使用。c++

  1. 使用邻接表存储图;less

  2. 使用标准STL的vector存储每一个点的全部邻接边;函数

  3. 使用pair记录当前搜索的点,pair<int,int>对:优化

    first记录最小距离,用以在优先队列中实现相似'最小堆优化';spa

    second记录该最小距离对应的点;code

  4. 使用priority_queue实现优化;(附使用方法)blog

  5. 一个细节:这是盲目检索,中途若D[i] < p.first,说明队列里的该点已经到达了,这个pair已经无效,直接continue;队列

 

  实现:ci

 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】it

  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;

相关文章
相关标签/搜索