pb_ds的优先队列实现dijkstra

用pb_ds的优先队列来做dijkstra。。据说noip能用哟。

先来篇关于仿函数的文章

由于pb_ds支持由迭代器访问元素,并且push操作会返回一个迭代器,merge操作会更新迭代器,相当于帮你实现了根据编号找元素的功能(每个元素对应一个迭代器)。但是由于dijkstra在取出堆顶元素以后还要知道堆顶元素的编号,于是我们可以自己搞一个结构体,然后弄一个仿函数。。这样就完成了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <functional>
  4 #include <ext/pb_ds/priority_queue.hpp>
  5 using namespace std;
  6 
  7 const int maxn=10005, maxm=5e6+5, INF=2147483647;
  8 
  9 struct heap_node{
 10     int value, id;
 11 };
 12 
 13 struct cmp{
 14     bool operator() (heap_node a, heap_node b){
 15         return a.value>b.value;
 16     }
 17 };
 18 
 19 __gnu_pbds::priority_queue<heap_node, cmp> heap;
 20 __gnu_pbds::priority_queue<heap_node, cmp>::point_iterator p[maxn];
 21 
 22 struct Edge{
 23     int to, next, v;
 24 };
 25 
 26 class Graph{
 27 private:
 28     int n, cntedge;
 29     int fir[maxn];
 30     Edge edge[maxm], link[maxn];
 31 public:
 32     Graph(){
 33         n=0, cntedge=0;
 34         memset(fir, 0, sizeof(fir));
 35         memset(edge, 0, sizeof(edge));
 36     }
 37 
 38     void addedge(int x, int y, int z){
 39         ++cntedge;
 40         edge[cntedge].to=y;
 41         edge[cntedge].v=z;
 42         edge[cntedge].next=fir[x];
 43         fir[x]=cntedge;
 44         return;
 45     }
 46 
 47     Edge *get_link(int x){
 48         int nowedge, nowson, cntlink=0;
 49         for (nowedge=fir[x]; nowedge;
 50              nowedge=edge[nowedge].next){
 51             nowson=edge[nowedge].to;
 52             ++cntlink;
 53             link[cntlink]=edge[nowedge];
 54         }
 55         link[0].v=cntlink;
 56         return link;
 57     }
 58 
 59 };
 60 
 61 int n, m, s;
 62 int dis[maxn];
 63 Graph g;
 64 
 65 int main(){
 66     for (int i=0; i<maxn; ++i)
 67         dis[i]=INF;
 68     scanf("%d%d%d", &n, &m, &s);
 69     int f, gg, w;
 70     for (int i=0; i<m; ++i){
 71         scanf("%d%d%d", &f, &gg, &w);
 72         g.addedge(f, gg, w);
 73     }
 74     heap_node ht;
 75     for (int i=1; i<=n; ++i){
 76         ht.id=i, ht.value=INF;
 77         p[i]=heap.push(ht);
 78     }
 79     dis[s]=0;
 80     ht.id=s, ht.value=0;
 81     heap.modify(p[s], ht);
 82     int now, nowson;
 83     Edge *link;
 84     for (int i=0; i<n; ++i){
 85         ht=heap.top();
 86         heap.pop();
 87         if (ht.value==INF) break;
 88         now=ht.id;
 89         link=g.get_link(now);
 90         for (int i=1; i<=link[0].v; ++i){
 91             nowson=link[i].to;
 92             if (dis[now]+link[i].v<dis[nowson]){
 93                 dis[nowson]=dis[now]+link[i].v;
 94                 ht.id=nowson, ht.value=dis[nowson];
 95                 heap.modify(p[nowson], ht);
 96             }
 97         }
 98     }
 99     for (int i=1; i<=n; ++i){
100         printf("%d ", dis[i]);
101     }
102     return 0;
103 }
原文地址:https://www.cnblogs.com/MyNameIsPc/p/7454805.html