堆(优先队列)模板

包含向上、向下两种维护方向,方便手动维护堆中单个元素(STL的priority_queue和make_heap没有这种功能T_T)

namespace heap{
    #define p(x) ((x) >> 1)
    #define l(x) ((x) << 1)
    #define r(x) (((x) << 1) + 1)
    #define maxn ((int)1e5)
    template <typename T>
        struct heap{
            T heap[maxn];
            int size;
            bool (*cmp)(T &a, T &b);
            void swap(T &a,T &b){T t = a;a = b;b = t;}
            bool Cmp(T &a, T &b){return a < b;}
            heap(){size = 0;cmp = Cmp;}
            heap(bool(*C)(T &a, T &b)){//参数为比较函数cmp的指针
                size = 0;
                cmp = C;
            }
            heap(T *begin, T *end){
                size = end - begin;
                int i = 0;
                for(;i < size;++i)
                    heap[i+1] = *(begin + i);
                for(i = size;i;--i)
                    maintainup(i);
            }
            void maintaindown(int k){
                int M = k;
                bool ctn;
                while(l(k) < size){
                    ctn = 0;
                    if(cmp(heap[l(k)], heap[M]))M = l(k);
                    if(r(k) < size && cmp(heap[r(k)],heap[M]))M = r(k);
                    if(k != M)swap(M, k), ctn = 1, k = M;
                    if(!ctn)return;
                }
            }
            void maintainup(int k){
                while(p(k) && cmp(heap[k], heap[p(k)]))
                    swap(heap[k], heap[p(k)]), k = p(k);
            }
            void insert(int k){
                heap[++size] = k;
                maintainup(k);
            }
            void pop(int k){
                heap[k] = heap[size--];
                if(cmp(heap[p(k)],heap[k])maintaindown(k);
                else maintainup(k);
            }
        };
}//namespce heap

时间: 2024-08-10 19:07:30

堆(优先队列)模板的相关文章

hdu 2544 单源最短路问题 dijkstra+堆优化模板

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 41168    Accepted Submission(s): 17992 Problem Description 在每年的校赛里.全部进入决赛的同学都会获得一件非常美丽的t-shirt.可是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的.所以如今他们想要寻

堆 (优先队列)举例

*/--> pre.src {background-color: Black; color: White;} 堆 (优先队列)举例 题目: 你需要驾驶一辆卡车行驶 l 单位距离.最开始的时候,卡车上有 p 单位的汽油.卡车每开 1 单位距离需要消费 1 单位的汽油.如果在途中汽车上的汽油耗尽,卡车就无法继续前行,因而无法到达终点.在途中一共有 n 个加油站.第 i 个加油站在距离起点 ai 单位距离的地方,最多可以给卡车加 bi 单位汽油.假设卡车的燃料箱的容量是无限大的,无论加多少油都没有问题

纯数据结构Java实现(6/11)(二叉堆&amp;优先队列)

堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). 但是二叉堆,需要满足一些特殊性质: 其一.二叉堆一定是一棵完全二叉树 (完全二叉树可以用数组表示,见下面) 完全二叉树缺失的部分一定是在右下方.(每层一定是从左到右的顺序优先存放) 完全二叉树的结构,可以简单理解成按层安放元素的.(所以数组是不错的底层实现) 其二.父节点一定比子节点大 (针对大顶堆

堆-优先队列

堆-优先队列 前置知识:二叉树. 参考资料 暂无 堆就是优先队列,可以用来解决动态区间查询最值问题. 堆就是一个完全二叉树,可以插入节点,删除根节点(也可以删除特定节点). 为了方便,普通的堆节点 \(i\) 的父亲就是 \([i\div2]\) (\([x]\) 表示不超过 \(x\) 的最大整数). 节点 \(i\) 的左儿子是 \(i\times2\),右儿子是 \(i\times2+1\). 对于一个大顶堆: 每次插入节点的时候,就把节点插在完全二叉树的最后,如果它比它的父亲节点大,就把

堆(优先队列)求huffman WPL

huffman编码中WPL等于没个结点到根结点的距离乘结点权值的总和,但我们也可以用另一种方法求WPL:如果huffman树只有一个结点,则WPL为根结点权值,否则WPL等于除了根结点以外的所有结点的权值之和. 我们可以用优先队列/堆实现这个过程: 1 //用优先队列求huffman编码中的WPL 2 #include <iostream> 3 using std::cin; 4 using std::cout; 5 using std::endl; 6 using std::swap; 7

【bzoj2151】种树(堆/优先队列+双向链表)

题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 这道题因为优先队列不怎么会用,而且手写堆的代码也不长,也想复习一下手写堆的写法……结果……WAWAWAWAW……看来我对堆的认识还是太浅薄了…… 这道题,如果没有限制不能选相邻的两个位置,那就肯定是贪心地选择m个美观度最大的位置种树.然而这里加了限制,那么我们可以注意到,如果一个美观度比较大的位置不被选上,一定是因为它两边的位置都被选了. 于是我们可以把n个美观度压进一个堆里,每

Running Median POJ - 3784 (对顶堆/优先队列)

For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far. Input The first line of input contains a single int

单调队列、单调栈、优先队列模板

目录 单调栈.单调队列及优先队列 1.单调队列 2.单调栈 3.优先队列 单调栈.单调队列及优先队列 1.单调队列 单调队列的描述:指队列中元素之间关系具有单调性,而且队首和队尾都可以出队,但是只有队尾可以进行入队操作.其重要作用是找到前n个后者后n个数的最值. 其具体操作是:假设单调队列是单调递减队列,假设在插入元素v时,将队列尾部的元素同v比较,如果队列尾部的元素不大于元素v,我们直接删除队尾元素,再将队尾元素与v比较,直至队尾元素比v大,这个时候我们将v插入队尾.其实现代码如下: int

堆(模板)

题目描述 如题,初始小根堆为空,我们需要支持以下3种操作: 操作1: 1 x 表示将x插入到堆中 操作2: 2 输出该小根堆内的最小数 操作3: 3 删除该小根堆内的最小数 输入输出格式 输入格式: 第一行包含一个整数N,表示操作的个数 接下来N行,每行包含1个或2个正整数,表示三种操作,格式如下: 操作1: 1 x 操作2: 2 操作3: 3 输出格式: 包含若干行正整数,每行依次对应一个操作2的结果. 输入输出样例 输入样例#1: 5 1 2 1 5 2 3 2 输出样例#1: 2 5 说明