美文网首页
树 | 优先队列

树 | 优先队列

作者: Vincy_ivy | 来源:发表于2019-06-04 23:52 被阅读0次

前提

原始堆

向其中插入数字3:先把3放到堆的最好,然后进行堆的大小颠倒。


插入堆的例子

堆的操作复杂度:
堆的两种操作所化的时间都和树的深度成正比。因此,如果一共有n个元素,那么每个操作可以在O(logn)的时间内完成。
堆的实现:
左儿子的编号是自己的编号X2+1;
右儿子的编号是自己的编号X2+2;

用数组便是二叉树时的编号

方法一

int heap[MAX_N],sz=0;
//上下不同层进行比较交换 
void push(int x){
    //i是自己节点的编号
    int i=sz++;//因为是数组的原因,因该是下标+1 
    while(i>0){
        //p为父亲节点的编号
        int p=(i-1)/2;
        //如果没有大小颠倒则退出
        if(heap[p]<=x)  break;
        //把父亲节点的数值放下来,而把自己提上去
        heap[i]=heap[p];
        i=p; 
    } 
    heap[p]=x;
}    

方法二

//不同一层进行比较交换 
int pop(){
    //最小值
    int ret=heap[0];
    //要提到根的数值
    int x=heap[--sz]; 
    //从根开始向下交换
    int i=0;
    while(i*2+1<sz){
        //比较儿子的值 
        int a=i*2+1,b=i*2+2;
        if(b<sz&&heap[b]<heap[a])
            a=b;
        //如果没有大小颠倒则退出
        if(heap[a]>=x)  break; 
           //把儿子的数值提上来
        heap[i]=heap[a];
        i=a; 
    } 
    heap[i]=x;
    return ret;
}

 
 

优先队列

STL中的priority_queue取出数值时得到的是最大值

#include <bits/stdc++.h>
using namespace std;
int main(){
    //声明
    priority_queue<int> pque;
    pque.push(3);
    pque.push(5);
    pque.push(1);

    //不断循环到空为止
    while(!pque.empty()){
        //获取并删除最大值
        printf("%d\n",pque.top());
        pque.pop(); 
    } 
    return 0; 
}
title
样例

代码

#include <bits/stdc++.h>
using namespace std;
int N,L,P,A[1000001],B[101];
void solve(){
    A[N]=L;
    B[N]=0;
    N++;

    //维护加油站的优先队列
    priority_queue<int> que;

    //ans:加油次数 ,pos:现在所在位置 ,tank:油箱中汽油的量
    int ans=0,pos=0,tank=P; 
    for(int i=0;i<N;i++){
        //接下来是要前进的距离;
        int d=A[i]-pos;
    
        //不断加油直到油量足够行驶到下一个加油站 
        while(tank-d<0){
            if(que.empty()){
                printf("-1");
                return;
            }
            tank+=que.top();
            que.pop();
            ans++;
        } 
        tank-=d;//加油加够后的一段路程用油箱里的油
        pos=A[i];
        que.push(B[i]); //这个才是加油站加油 
    }
    printf("%d\n",ans);
}

int main(){
    cin>>N>>L>>P;
    for(int i=0;i<N;i++)
        scanf("%d",&A[i]);
    for(int i=0;i<N;i++)
        scanf("%d",&B[i]);
    solve();
} 

 
 

Expedition

最近因为期末的原因有点小久没有看白书了//我对不起你~LXY说软院也要有ACM训练营了加油!
这道题是一步一步入坑,然后在一步一步地走出来的
1.没想到会用贪心,然后就直接打了,emmm~runtime error
2.用了贪心后,排序那里应该是从大到小,从与终点town离得最远的开始
3.leng[N].A=0;不是等于L;因为之后还要用L-0;

Code

//#include<bits/stdc++.h>
using namespace std;
int N,L,P;
struct len{
    int A,B;
}leng[10001];

bool cmp(len l1,len l2){
    return l1.A>l2.A;
}

int main(){
    freopen("data","r",stdin);
    cin>>N;
    for(int i=0;i<N;i++){
        cin>>leng[i].A>>leng[i].B;//A为距离B为可用的燃料量 
    }
    cin>>L>>P;//L为全长,P为初始的燃料数 
    priority_queue<int> que;
    leng[N].A=0;
    leng[N].B=0;
    N++;
    sort(leng,leng+N,cmp);
    int ans=0,pos=0,tank=P;
    for(int i=0;i<N;i++){
        int d=L-leng[i].A-pos;//先求出距离叭 
        while(tank-d<0){
            if(que.empty()){
                cout<<"-1"<<endl;
                return 0;
            }
            tank+=que.top();
            que.pop();
            ans++;
        }
        tank-=d;
        pos=L-leng[i].A;
        que.push(leng[i].B);
    }
    cout<<ans<<endl;
    return 0;
}

 
 

Fence Repair

学会了优先队列的方法后,我现在立刻马上right now收回在哈夫曼编码中说的某些话
用优先队列快了很多。

Code

//#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int L[50001],N;
int main(){
    cin>>N;
    for(int i=0;i<N;i++)
        cin>>L[i];
    ll ans=0;
    //声明一个从小到大取出数值的优先队列
    priority_queue<int,vector<int>,greater<int> > que;
    for(int i=0;i<N;i++)
        que.push(L[i]);
    //循环到只剩下一块木板为止 
    while(que.size()>1){
        //取出最短板和次短板
        int l1,l2;
        l1=que.top();
        que.pop();
        l2=que.top();
        que.pop();
        //两块木板合并 
        ans+=l1+l2;
        que.push(l1+l2);
    } 
    cout<<ans;
    return 0;
}

相关文章

  • 树 | 优先队列

    前提 向其中插入数字3:先把3放到堆的最好,然后进行堆的大小颠倒。 堆的操作复杂度:堆的两种操作所化的时间都和树的...

  • 第五讲-树(下)

    树(下) 堆 优先队列:特殊的“队列”,取出元素的顺序是一招元素的“优先权(关键字)”大小,而不是队列的先后顺序。...

  • 《恋上数据结构与算法一》笔记(十七)优先级队列

    目录 优先级队列 优先级队列的应用场景举例 优先队列的底层实现 习题 一 优先级队列 优先级队列也是个队列,因此也...

  • 《数据结构与算法》总结(八)优先级队列

    目录 优先级队列 优先级队列的应用场景举例 优先队列的底层实现 习题 一 优先级队列 优先级队列也是个队列,因此也...

  • 完全二叉树实现优先队列与堆排序

    本文的目标是要做出优先队列和堆排序两个Demo。 完全二叉树 优先队列 堆排序 完全二叉树 完全二叉树的定义是建立...

  • 深度优先遍历相当于树的前序遍历,递归思想 广度优先遍历相当于树的层序遍历,队列思想

  • 目录

    数组 动态数组 链表 栈 队列 优先队列 树 二叉树(广义)二叉堆二叉查找树AVL树 并查集 散列表

  • Swift 数据结构与算法实现

    用 Swift 实现了 Trie 字典树、并查集、堆和优先队列、哈希表、红黑树、集合与映射、链表、数组、栈、队列、...

  • python数据结构教程 Day13

    本章内容: 利用二叉堆实现优先队列 二叉堆的python实现 二叉查找树及操作 一、优先队列Priority Qu...

  • 栈 队列 queue 队列的基本应用:广度优先遍历 树;层序遍历 图;无权图的最短路径 树 二分搜索树:二叉树:

网友评论

      本文标题:树 | 优先队列

      本文链接:https://www.haomeiwen.com/subject/skaitctx.html