stl是一个c++中很好的一个功能,但是stl如果使用不当也会酿成大错,而且stl还十分的慢,如果不开O2优化,会比手打慢了好几倍。虽说如此,但stl还是深受c++程序员喜爱,今天我们就来讲讲STL中的优先队列:priority_pueue。
首先来讲讲他的定义方式:
最简单的定义方式:priorithy_pueue <变量的类型> q;
注意这是大根堆,如果要定义一个小根堆的话要这么定义: priorithy_pueue <变量的类型,vector<变量的类型,greadter<变量的类型> > q或者写一个cmp函数。其实还是很简单的。
再来讲讲优先队列的几个常用的函数:
函数名 功能 时间复杂度
size 返回堆的大小 O(1)
top 返回堆的最大值或最小值 O(1)
push 在堆中插入一个值 O(log(n))
pop 删除堆的最大值或最小值 O(log(n))
empty 判断堆是否为空 O(1)
现在来看一到经典的题目:合并果子
自己手写堆的方法:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std;
int a[1000001],head=0;
void push(int k,int x) {
if(x<a[k>>1]) {
int y=a[k>>1];
a[k>>1]=x;
a[k]=y;
push(k>>1,x);
}
}
void pop(int k) {
if(k*2>head||k*2+1>head)
return ;
if((a[(k<<1)+1]<a[k<<1]||a[k<<1]>a[k])&&a[k*2+1]<a[k]) {
int y=a[(k<<1)+1];
a[(k<<1)+1]=a[k];
a[k]=y;
pop((k<<1)+1);
} else if(a[k]>a[k<<1]) {
int y=a[k<<1];
a[k<<1]=a[k];
a[k]=y;
pop(k<<1);
}
}
int top() {
return a[1];
}
int main() {
memset(a,0xfffffff,sizeof(a));
int n,k,l,js=0;
cin>>n;
for(int i=1; i<=n; i++) {
head++;
cin>>a[head];
if(head!=1)
push(head,a[head]);
}
for(int i=1; i<n; i++) {
k=top();
a[1]=a[head];
pop(1);
head--;
l=top();
a[1]=a[head];
pop(1);
head--;
js+=k+l;
head++;
a[head]=k+l;
if(head!=1)
push(head,k+l);
}
cout<<js;
return 0;
}
用STL的方法:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<queue>
using namespace std;
priority_queue <int,vector<int>,greater<int> > a;
int main() {
int n,k,l,js=0;
cin>>n;
for(int i=1; i<=n; i++) {
cin>>k;
a.push(k);
}
for(int i=1; i<n; i++) {
k=a.top();
a.pop();
l=a.top();
a.pop();
js+=k+l;
a.push(k+l);
}
cout<<js;
return 0;
}