优先队列
优先队列:
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。
最近刚学的优先队列 其实就是队列多了几个优先级问题,如果有多层优先级就要定义结构体。
优先队列的实现分为:大根堆和小根堆。
大根堆的定义:priority_queue<int , vector<int>, less<int> > p;///大根堆
小根堆的定义:priority_queue<int , vector<int>, greater<int> > q;///小根堆
大根堆就是大的先出队,小根堆就是小的先出队,按照题目条件进行重载
数据结构课程中学习到的哈夫曼树也可以用优先队列来解决
重载:
bool operator > (const node &a,const node &b)///重载运算符 如果是小根堆写 >号
{
if(a.a==b.a)
return a.b>b.b;
return a.a>b.a;
}
(上面的重载要根据题目意思来写)
基本的一些操作:
q.push(x);///入队
q.pop()///出队
q.top()///顶
q.size()///队列元素的个数
例题:
HDU1896 的扔石头问题可以用优先队列解决
代码:
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 struct node 7 { 8 int a;///所在位置 9 int b;///能扔多远 10 }; 11 bool operator > (const node &a,const node &b)///重载运算符 如果是小根堆写 >号 12 { 13 if(a.a==b.a) 14 return a.b>b.b; 15 return a.a>b.a; 16 } 17 int main() 18 { 19 int n,a,t,b; 20 char x[15]; 21 scanf("%d",&t); 22 while(t--) 23 { 24 node p; 25 priority_queue<node,vector<node>, greater<node> >q; 26 scanf("%d",&n); 27 for(int i=1; i<=n; i++) 28 { 29 scanf("%d %d",&a,&b); 30 p.a=a; 31 p.b=b; 32 q.push(p); 33 } 34 int num=0; 35 while(q.size()>0) 36 { 37 num++; 38 if(num&1) 39 { 40 p=q.top(); 41 p.a+=p.b; 42 q.push(p); 43 } 44 q.pop(); 45 } 46 printf("%d\n",q.top().a); 47 } 48 }
加入一些优先队列中关于重载的笔记
#include<bits/stdc++.h> #include<queue> using namespace std; struct Node { int to,w; Node(int tt,int cc) { to=tt; w=cc; } friend bool operator < (const Node &a, const Node &b) { return a.w >b.w; } }; priority_queue<Node,vector<Node>,less<Node> >q;///(大根堆less 只能用<号重载) (小根堆greater 只能用>号重载) int main() { q.push(Node(2,3)); q.push(Node(1,2)); q.push(Node(2,4)); while(!q.empty()) { Node now=q.top(); printf("%d %d\n",now.to,now.w); q.pop(); } } ///优先队列笔记 (大根堆less 只能用<号重载) (小根堆greater 只能用>号重载) priority_queue<Node,vector<Node>,less<Node> >q; 这是大根堆,所以重载运算符要写 < 号, 在return那里,因为大根堆默认就是先出大的, 所以写的符号和重载的符号(<)一样就是默认的大的先出 如果写的是和重载的相反(>)就是小的先出。 同理 小根堆一样