1.最小堆、最大堆

priority_queue<int,vector<int>,greater<int> > f; //最小堆(后面的数逐渐greater)

priority_queue<int,vector<int>,less<int> > f;//最大堆(后面的数逐渐less)

(1).合并果子

https://www.vijos.org/p/1097

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <stdbool.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std; priority_queue<int,vector<int>,greater<int> > f; int main()
{
long n,i,a,x,y=;
scanf("%ld",&n);
for (i=;i<=n;i++)
{
scanf("%ld",&a);
f.push(a);
}
for (i=;i<n;i++)
{
x=f.top();
f.pop();
x+=f.top();
f.pop();
f.push(x);
y+=x;
}
printf("%ld",y);
return ;
}

2.自定义

测试:

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stdbool.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 100000+5
#define inf 100000+5 long f[maxn],pos[maxn]; //×î´ó¶Ñ
struct cmp1
{
bool operator() (long a,long b)
{
return f[a]<f[b];
}
}; //×îС¶Ñ
struct cmp2
{
bool operator() (long a,long b)
{
return f[a]>f[b];
}
}; //Ç°1/2:a ºó1/2£ºb
priority_queue<int,vector<int>,cmp1 > a;
priority_queue<int,vector<int>,cmp2 > b; int main()
{
long n,d,i;
scanf("%ld",&n);
for (i=;i<=n;i++)
{
scanf("%ld",&f[i]);
// a.push(i);
b.push(i);
}
// while (!a.empty())
while (!b.empty())
{
// printf("%ld ",f[a.top()]);
// a.pop();
printf("%ld ",f[b.top()]);
b.pop();
}
return ;
}
/*
5
2 4 5 1 3
*/

最短路用堆实现,时间复杂度O(nlogn),其实可以用下面的3方法实现,使堆中的数据永远小于等于n个,但是编写比较复杂

两道例题:

http://www.cnblogs.com/cmyg/p/8727643.html

3.对于需要修改、删除堆里的数据,需要自行写堆(优先队列)  参见算法导论

以下是使用优先队列修改、删除堆里的数据,发生错误的案例(代入数据):

 //要删除指定值的话只能自己写一个优先队列
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stdbool.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 100000+5
#define inf 100000+5 long f[maxn],pos[maxn]; //最大堆
struct cmp1
{
bool operator() (long a,long b)
{
return f[a]<f[b];
}
}; //最小堆
struct cmp2
{
bool operator() (long a,long b)
{
return f[a]>f[b];
}
}; //从小到大排序
//前(n+1)/2个数:a(最大堆)
//后n/2个数:b(最小堆)
//中位数永远是a的最大值
//增添和删除:也许需要a的最大值移向b或b的最小值移向a
priority_queue<int,vector<int>,cmp1 > a;
priority_queue<int,vector<int>,cmp2 > b; void change()
{
long d;
if (a.size()<b.size())
{
d=b.top();
b.pop();
a.push(d);
pos[d]=;
}
else if (a.size()>b.size()+)
{
d=a.top();
a.pop();
b.push(d);
pos[d]=;
}
} int main()
{
long n,g;
char s[];
scanf("%ld",&n);
while (n)
{
n--;
scanf("%s",s);
if (strcmp(s,"Pop")==)
{
if (g==)
{
printf("Invalid\n");
continue;
}
printf("%ld\n",f[g]);
if (pos[g]==)
{
f[g]+=inf; printf("--%ld\n",a.top()); a.pop(); printf("--%ld\n",a.top());
//这里错了
}
else
{
f[g]-=inf;
b.pop();
}
g--;
change();
}
else if (strcmp(s,"Push")==)
{
g++;
scanf("%ld",&f[g]);
if (a.empty() || f[g]<=f[a.top()])
{
a.push(g);
pos[g]=;
}
else
{
b.push(g);
pos[g]=;
}
change();
}
else
{
if (g==)
printf("Invalid\n");
else
printf("%ld\n",f[a.top()]);
}
}
return ;
}
/*
100
Push 1
PeekMedian
Push 2
PeekMedian
Push 3
PeekMedian
Push 4
PeekMedian
Push 5
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop 100
Push 5
PeekMedian
Push 4
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop */

3.1 求第k大,k的值每次最多变化为1

求中位数

https://www.patest.cn/contests/gplt/L3-002

Solution:

分成两个堆,

对数从小到大排序
前(n+1)/2个数:a(最大堆)
后n/2个数:b(最小堆)
中位数永远是a的最大值
增添和删除:也许需要a的最大值移向b或b的最小值移向a

注意pos和input数组,这个是用于定位的,从而可以修改数据,删除数据

 //还可以求第k大(k值固定) 

 //要删除指定值的话只能自己写一个优先队列
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stdbool.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <iostream>
using namespace std;
#define maxn 100000+5
#define inf 100000+5 struct node
{
long d,g;
}; long f[maxn],treenum[maxn];
//posa[i],posb[i]:a/b中第i个点在输入中的位置
//input[i]:输入中第i个点在树的位置(pos标记是在哪棵树)
long a[maxn],b[maxn],posa[maxn],posb[maxn],input[maxn]; //最大堆
struct cmp1
{
bool operator() (long a,long b)
{
return f[a]<f[b];
}
}; //最小堆
struct cmp2
{
bool operator() (long a,long b)
{
return f[a]>f[b];
}
}; //从小到大排序
//前(n+1)/2个数:a(最大堆)
//后n/2个数:b(最小堆)
//中位数永远是a的最大值
//增添和删除:也许需要a的最大值移向b或b的最小值移向a
//priority_queue<int,vector<int>,cmp1 > a;
//priority_queue<int,vector<int>,cmp2 > b; void up_min(long t[],long pos[],long input[],long i)
{
long j,temp;
while (i>)
{
j=i>>;
//j<i
if (t[j]>t[i])
{
temp=t[i];
t[i]=t[j];
t[j]=temp; temp=pos[i];
pos[i]=pos[j];
pos[j]=temp; input[pos[i]]=i;
input[pos[j]]=j;
}
else
break;
i=j;
}
} void down_min(long t[],long pos[],long input[],long i)
{
long j,temp;
while (( i<<)<=t[])
{
j=i<<;
if (j!=t[] && t[j+]<t[j])
j=j|;
//i<j
if (t[i]>t[j])
{
temp=t[i];
t[i]=t[j];
t[j]=temp; temp=pos[i];
pos[i]=pos[j];
pos[j]=temp; input[pos[i]]=i;
input[pos[j]]=j;
}
else
break;
i=j;
}
} void push_min(long t[],long pos[],long input[],struct node p)
{
t[]++;
t[t[]]=p.d;
pos[t[]]=p.g;
input[p.g]=t[];
up_min(t,pos,input,t[]);
} void pop_min(long t[],long pos[],long input[])
{
t[]=t[t[]];
pos[]=pos[t[]];
input[pos[]]=;
t[]--;
down_min(t,pos,input,);
} void minus_min(long t[],long pos[],long input[],long w,long d)
{
t[w]-=d;
up_min(t,pos,input,w);
} void plus_min(long t[],long pos[],long input[],long w,long d)
{
t[w]+=d;
down_min(t,pos,input,w);
} void up_max(long t[],long pos[],long input[],long i)
{
long j,temp;
while (i>)
{
j=i>>;
//j<i
if (t[j]<t[i])
{
temp=t[i];
t[i]=t[j];
t[j]=temp; temp=pos[i];
pos[i]=pos[j];
pos[j]=temp; input[pos[i]]=i;
input[pos[j]]=j;
}
else
break;
i=j;
}
} void down_max(long t[],long pos[],long input[],long i)
{
long j,temp;
while ((i<<)<=t[])
{
j=i<<;
if (j!=t[] && t[j+]>t[j])
j=j|;
//i<j
if (t[i]<t[j])
{
temp=t[i];
t[i]=t[j];
t[j]=temp; temp=pos[i];
pos[i]=pos[j];
pos[j]=temp; input[pos[i]]=i;
input[pos[j]]=j;
}
else
break;
i=j;
}
} void push_max(long t[],long pos[],long input[],struct node p)
{
long i,j,temp;
t[]++;
t[t[]]=p.d;
pos[t[]]=p.g;
input[p.g]=t[];
up_max(t,pos,input,t[]);
} void pop_max(long t[],long pos[],long input[])
{
t[]=t[t[]];
pos[]=pos[t[]];
input[pos[]]=;
t[]--;
down_max(t,pos,input,);
} void plus_max(long t[],long pos[],long input[],long w,long d)
{
t[w]+=d;
up_max(t,pos,input,w);
} void minus_max(long t[],long pos[],long input[],long w,long d)
{
t[w]-=d;
down_max(t,pos,input,w);
} long size(long t[])
{
return t[];
} struct node top(long t[],long pos[])
{
struct node p;
p.d=t[];
p.g=pos[];
return p;
} bool empty(long t[])
{
if (t[]==)
return true;
else
return false;
} void change()
{
struct node cond;
long d;
if (size(a)<size(b))
// if (a.size()<b.size())
{
cond=top(b,posb);
pop_min(b,posb,input);
push_max(a,posa,input,cond);
// d=b.top();
// b.pop();
// a.push(d);
treenum[cond.g]=;
}
else if (size(a)>size(b)+)
// else if (a.size()>b.size()+1)
{
cond=top(a,posa);
pop_max(a,posa,input);
push_min(b,posb,input,cond);
// d=a.top();
// a.pop();
// b.push(d);
treenum[cond.g]=;
}
} int main()
{
struct node cond;
long n,g;
char s[];
a[]=; b[]=;
scanf("%ld",&n);
while (n)
{
n--;
scanf("%s",s);
if (strcmp(s,"Pop")==)
{
if (g==)
{
printf("Invalid\n");
continue;
}
printf("%ld\n",f[g]);
if (treenum[g]==)
{
// f[g]+=inf;
// a.pop();
plus_max(a,posa,input,input[g],inf);
pop_max(a,posa,input);
}
else
{
// f[g]-=inf;
// b.pop();
minus_min(b,posb,input,input[g],inf);
pop_min(b,posb,input);
}
g--;
change();
}
else if (strcmp(s,"Push")==)
{
g++;
scanf("%ld",&f[g]);
// if (a.empty() || f[g]<=f[a.top()])
if (empty(a) || f[g]<=top(a,posa).d)
{
cond.d=f[g];
cond.g=g;
// a.push(g);
push_max(a,posa,input,cond);
treenum[g]=;
}
else
{
cond.d=f[g];
cond.g=g;
// b.push(g);
push_min(b,posb,input,cond);
treenum[g]=;
}
change();
}
else
{
if (g==)
printf("Invalid\n");
else
// printf("%ld\n",f[a.top()]);
printf("%ld\n",top(a,posa).d);
}
}
return ;
}
/*
100
Push 1
PeekMedian
Push 2
PeekMedian
Push 3
PeekMedian
Push 4
PeekMedian
Push 5
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop 100
Push 5
PeekMedian
Push 4
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop
PeekMedian
Pop */

3.2 求第k大的数(k永远不变)

前k大的数放入最小堆a,其它的数放入最大堆b

添加数据:数据放入堆a,若堆a的大小大于k,则取最小的数放入堆b

修改数据:修改后根据情况是否把一个数从a移至b或从b移至a

c++优先队列(堆)的更多相关文章

  1. Java学习笔记--PriorityQueue(优先队列)(堆)

    PriorityQueue(优先队列)实际上是一个堆(不指定Comparator时默认为最小堆)队列既可以根据元素的自然顺序来排序,也可以根据 Comparator来设置排序规则.队列的头是按指定排序 ...

  2. Expedition---poj2431(优先队列-堆的实现)

    题目链接:http://poj.org/problem?id=2431 题意:一辆卡车需要行驶 L 距离,车上油的含量为 P,在行驶的过程中有 n 个加油站 每个加油站到终点的距离是ai,每个加油站最 ...

  3. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  4. dij最短路优先队列堆的时候,加边

    不能用全局数组d[u]>d[rhs.u]. 这样后面会修改d[u]值然而本来里面的点顺序不该修改,却被修改了. 应该用栈还存进去的临时变量,比如d>rhs.d. 优先队列重载小于号'< ...

  5. Dijkstra+优先队列 堆优化

    关于堆优化 传统\(Dijkstra\),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂(\(O(V2+E) ...

  6. CJOJ 2484 函数最小值 / Luogu 2085 函数最小值(STL优先队列,堆)

    CJOJ 2484 函数最小值 / Luogu 2085 函数最小值(STL优先队列,堆) Description 有n个函数,分别为F1,F2,...,Fn.定义 \(Fi(x)=Aix^2+Bix ...

  7. 浅谈堆-Heap(一)

    应用场景和前置知识复习 堆排序 排序我们都很熟悉,如冒泡排序.选择排序.希尔排序.归并排序.快速排序等,其实堆也可以用来排序,严格来说这里所说的堆是一种数据结构,排序只是它的应用场景之一 Top N的 ...

  8. 算法导论 第六章 2 优先队列(python)

    优先队列:     物理结构: 顺序表(典型的是数组){python用到list}     逻辑结构:似完全二叉树 使用的特点是:动态的排序..排序的元素会增加,减少#和快速排序对比 快速一次排完 增 ...

  9. [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)

    [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...

随机推荐

  1. AbstractFactory(PeopleSkin)

    使用抽象工厂模式,完成下述产品等级结构: 实现 UML类图 public class BlackFactory implements MWFactory{ public Man produceMan( ...

  2. Java script 中的面向对象1

    Java script 中的面向对象 对象 对象是Javascript的基本数据类型,对象是一种复合值,将很多的键值对聚合在一起使用.对象可看做是属性的无序集合,每个属性都是一个名/值对.属性名其实是 ...

  3. Leetcode题库——11.盛最多水的容器

    @author: ZZQ @software: PyCharm @file: maxArea.py @time: 2018/10/11 21:47 说明:给定 n 个非负整数 a1,a2,...,an ...

  4. ssh框架配置数据源 数据库连接没有正常释放

    通过多天的改bug 对数据源这个东西了解多了..    我发现 spring+hibernate下  申请数据库连接是在一个action方法内  也就是说  action 里面有三个 service方 ...

  5. POJ 2104 K-th Number 主席树(区间第k大)

    题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...

  6. 软工实践l练习一一利用github托管项目

    这次实践的主题是在windows环境下将项目通过git将项目托管到github上.通过实践,基本掌握一些git命令的使用,在github上注册账号并学会创建repositly和organization ...

  7. 读《我是IT小小鸟》有感

    我是一只IT小小鸟,我与IT结缘.书中是作者对个人经历与经验在IT下的体会,却给了我们很好的借鉴. IT这门行业,不仅仅再局限于如我们高中老师教学所要求的内容.IT更加开放,可以通过GitHub.CS ...

  8. Good Time 冲刺 六

    一.今日完成任务情况 第六天 日期:2018.6.19 王怡镔:今天完善了页面,对部分不足进行改进. 于鑫宇:对界面进行完善. 胡雅馨:今天完成前端页面,并改善后端,完善项目. 黄 鹤:做完最后的打卡 ...

  9. TP5 多入口文件配置的坑

    闲话不多说,TP5(5.0.20) 在配置多入口文件的时候你是否遇到过一下的问题呢? 开发设计的需求吧网站拆分为前台.后台.API 3 个模块,对应的也需要3个入口文件,后台和API入口文件是用PAT ...

  10. [转帖] Linux buffer 和 cache相关内容

    Linux中Buffer/Cache清理 Lentil2018年9月6日 Linux中的buff/cache可以被手动释放,释放缓存的代码如下: https://lentil1016.cn/linux ...