STL之优先队列

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值