中级篇——优先队列

优先队列与一般队列不同,插入新元素时不是直接将新元素插入到队尾,而是根据优先级插入到其所在优先级的相应位置。

优先队列分为两种:最大优先队列和最小优先队列。故每次取出的是队列中最大优先级和最小优先级。可以根据默认的优先级排序也可自定义优先级排序。

所需头文件:“queue.h”和“functional.h”。

一、优先队列支持的操作

q.size();  //返回队列元素个数
q.empty(); //队列是否为空,空返回true,否则返回false
q.pop();   //删除队首元素,不返回其值
q.push(x); //将元素x按优先级插入队列
q.top();   //返回队首元素但不删除

二、常见的几种优先队列用法

(1)按默认优先级

priority_queue<int>que;

定义一个名为que的int型优先队列,按照系统默认的优先级进行排序。

(2)自定义升序优先级

定义方法有两种:1.采用结构体定义。2.采用functional头文件内定义。

//采用结构体定义升序
struct cmp1
{
    bool operator()(int &a,int &b)
        return a>b;    //最小值优先的排列    
};

//采用functional内定义
struct num1
{
    bool operator < (const num&a) const
    {
        return x>a.x;  //最小值优先的排列
    }
};
推荐使用结构体定义,简单易懂!

(3)定义降序优先级

同样有结构体定义和functional内定义。

//采用结构体定义降序
struct cmp2
{
    bool operator()(int &a,int &b)
    {
        return a>b;  //最大值优先的排列
    }
};

//采用functional内定义
struct num2 
{
    int x;
    bool operator <(const num2 &a)const
    {
        return x<a.x; //最大值优先的排列
    }
}
优先级构造完成,接下来就是构造队列并采用所定义的优先级排列

将数组a[]插入队列中
//结构体定义
for(int i=0;a[i];i++)
{
    que1.push(a[i]);
    que2.push(a[i]);
}
//内定义插入
for(int i=0;num1[i].x;i++)
    que3.push(num1[i].x);
for(int i=0;num2[i].x;i++)
    que4.push(num2[i].x);

分别输出que1,2
cout<<"输出que1:";
while(!que1.empty())
{
    cout<<que1.top()<<" ";
    que1.pop();
}
cout<<endl;

cout<<"输出que2:";
while(!que2.empty())
{
    cout<<que2.top()<<" ";
    que2.pop;
}
cout<<endl;

cout<<"输出que3:";
while(!que3.empty())
{
    cout<<que3.top()<<" ";
    que3.pop();
}
cout<<endl;

cout<<"输出que4:";
while(!que4.empty())
{
    cout<<que4.top<<" ";
    que4.pop();
}
cout<<endl;

典例:http://poj.org/problem?id=3190

题意:

奶牛要在指定的时间挤奶,一台机器只能给一头奶牛挤奶,问最少要几台机器。
思路:用STL里的优先队列,判断空闲机器是否满足下一头奶牛的挤奶时间,满足就让挤完奶的奶牛出队把机器编号给下一头奶牛,下一头奶牛入队,否则机器+1,下一头奶牛入队.
注意:输出的顺序和输入的顺序相同,在输入的时候把下标一起存入结构体,另外开一个数组记录机器的编号,在排序后下标就不会乱了。
AC代码:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
struct pa
{
    int s,e,x;//开始时间,结束时间,牛的序号
    //队列按照结束时间降序排列
    bool operator <(const pa&c) const
    {
        if(e==c.e) return s>c.s;//结束时间相同,按开始时间降序排列
        else return e>c.e;
    }
}a[50005];
priority_queue<pa> que;//在pa结构体的基础上建立队列que
int cmp1(const pa&a,const pa&b)
{
    if(a.s==b.s) return a.e<b.e;
    else return a.s<b.s;
}
int b[50005]; //数组b记录第i头牛在第几条生产线上
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i].s>>a[i].e;
            a[i].x=i;
        }
        sort(a,a+n,cmp1);
        que.push(a[0]);
        b[a[0].x]=1;
        int cnt=1;
        for(int i=1;i<n;i++)
        {
            int t=que.top().e;
            if(a[i].s>t) 
            {
                b[a[i].x]=b[que.top().x];
                que.pop();
            }
            else 
            {
                cnt++;
                b[a[i].x]=cnt;
            }
            que.push(a[i]);
        }
        cout<<cnt<<endl;
        for(int i=0;i<n;i++)
            cout<<b[i]<<endl;
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值