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. linux 安装配置zookeeper脚本

    #!/bin/bash # automatic install zookeeper echo "========= Start to install zookeeper ========== ...

  2. ffplay.exe操作方式

    大牛博客: 博文名称:[总结]FFMPEG视音频编解码零基础学习方法 博文链接:http://blog.csdn.net/leixiaohua1020/article/details/15811977 ...

  3. 记一次centos6升级salt-minion启动失败的问题

    记一次centos6升级salt-minion启动失败的问题 作者:耀耀 blog:https://www.liuyao.me 一.起因 升级Salt-minion后 使用/etc/init.d/sa ...

  4. Python脚本文件(.py)打包为可执行文件(.exe)即避免命令行中包含Python解释器

      在最近的软件工程作业中用到了将Python脚本转化为exe文件这一过程,网上各种博客介绍了很多,有些东西都不完全,我也是综合了很多种方法最后才实现的,我就把这些整理出来,希望可以帮到大家~ 一.环 ...

  5. java把map转json

    JSONUtils.toJSONString(requestMap);    com.alibaba.fastjson.JSON <!-- https://mvnrepository.com/a ...

  6. java实验三实验报告

    一.实验内容 1. XP基础 2. XP核心实践 3. 相关工具 二.实验过程(本次试验是在自己电脑上完成,没有使用实验楼) (一)敏捷开发与XP 1.XP是以开发符合客户需要的软件为目标而产生的一种 ...

  7. 2017 Summary

    几门课 基础电路与电子学 知道了一些二极管三极管的基本基本很基本的那种物理知识吧,但是毕竟我是从电信转专业过来的,所以说我内心就是逃避模电这样的课的.上课基本没听,后面只是死命复习了一周,考的还可以. ...

  8. testng对执行失败的用例,再次执行

    前段时间在网络上看到通过重写TestNG的接口,可以再次执行失败的测试用例,于是学习了,我之前的做法是当自己的脚本中碰到异常,就自动调用方法本身来达到再次执行用例的目的,这个过程中有设定重试的次数 对 ...

  9. mysql 函数示例(转)

    MySQL函数大全及用法示例 1.字符串函数ascii(str)   返回字符串str的第一个字符的ascii值(str是空串时返回0)  mysql> select ascii('2');   ...

  10. 笔记之分布式文件系统(DFS)

    不知何故,老外都挺喜欢使用DFS,但是国内公司用这个的不多.一个具体的需求就是,备份服务器在国外,所以启用DFS把国内的数据同步一份到国外进行备份.最近有机会接触DFS,把一些心得体会记录一下. 1. ...