priority_queue(優先隊列)的用法(包括pbds)


置頂!!!

有時候在定義的時候,不要把兩個<<或者>>連在一起寫,以免被編譯器錯誤理解!!!!

頭文件

#include <queue>

queue的一般用法不再敘述

類型名 priority_queue

常用函數

(設變量名為q)

q.pop();
q.push(x);
q.size();
q.empty();
q.top();   //注意與一般的queue中的q.front()不同

一般默認大根堆

使用小根堆的方法

priority_queue<int,vector<int>,greater<int>> q; //當然大根堆就是less

自定義優先級:

方法一:

struct rec{
    int a,b
};

struct cmp {     
    bool operator ()(rec x, rec y)     
    {        
        return x.a > y.a; //結構體中,x小的優先級高 (意即大於號出來的是小根堆)   
    }
};

priority_queue<int, vector<int>, cmp> q; //定義方法

方法二:

struct node {     
    int x, y;     
    friend bool operator < (node a, node b)     
    {         
        return a.x > b.x;    //結構體中,x小的優先級高 (意即大於號出來的是小根堆)    
    }
};

priority_queue<node>q; //定義方法

//通過自定義operator<操作符來比較元素中的優先級。

//在重載”<”時,最好不要重載”>”,可能會發生編譯錯誤

下面是平板電視的部分

pb_ds頭文件

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
//這個是pb_ds要求的頭文件,注意平板電視里面涉及的頭文件都不在bits/std標准庫中

優先隊列(堆)要求的頭文件

#include <ext/pb_ds/priority_queue.hpp>

命名空間

using namespace __gnu_pbds;
(當心前面是兩個下划線啊,當心啊!!!)

//當然pb_ds還有其他非常好用的數據結構,只不過我現在還不會

//留個坑待填(雖然可能不會填)

常用函數

與priority_queue基本相同

有一些拓展的函數

q.join(q1);  //把q1全部合並到q中去,並且把q1清空
q.point_iterator; //對應某元素的迭代器
q.erase(point_iterator it);  //刪除對應點
q.modify(point_iterator it,const_reference r_new_val); //修改對應點的值(這是優化dijkstra神方法,均攤復雜度O(1))
//迭代器這一部分我不會啊  又留了一個坑
//如果學會就好了,這個確實很實用

定義方法

__gnu_pbds::priority_queue<int,greater<int>,TAG> Q;//小根堆,大根堆寫less<int>
//注意這個里面的前面的__gnu_pbds::不要省略,因為雖然定義了命名空間,但是因為標准庫里面也有priority_queue,這個就很ambigious

其中的TAG為類型,有以下幾種:

pairing_heap_tag
thin_heap_tag
binomial_heap_tag
rc_binomial_heap_tag 
binary_heap_tag
其中pairing_help_tag最快

關於自定義的比較

對於上方的兩種方式,經過我的多次實驗,發現只有第一個可用,第二種無論我怎么調都是CE,這個與優先隊列的定義方法有關

就采用第一種罷!

對於第一種,結構體定義都是一樣的

定義方法改成這樣
__gnu_pbds::priority_queue<rec,cmp,pairing_heap_tag> Q;

大概就是以上部分😋

留坑代填


免責聲明!

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



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