• 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 }
  • 相关阅读:
    MyEclipse使用经验总结
    CSDN-markdown编辑器使用简介
    struts2提供的校验器
    JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
    JAVA中文字符编码问题详解 控制台输出
    Statement、PreparedStatement
    struts2 文件上传
    SQL RIGHT JOIN 关键字:语法及案例剖析
    SQL LEFT JOIN 关键字:语法及案例剖析
    SQL INNER JOIN 关键字:语法及案例剖析
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7454805.html
Copyright © 2020-2023  润新知