1.定义:priority_queue翻译为优先队列
2.性质:队列自动排序;
3.使用:
priority_queue<数据类型,vector<数据类型>,greater<数据类型> > 从小到大
priority_queue<数据类型,vector<数据类型>,less<数据类型> > 从大到小
priority_queue<数据类型,vector<数据类型> > 默认从大到小
比较函数
struct stu{
int x,y,sum;};
bool operator<(const stu &a,const stu &b)
{
return a.x>b.x; // 指根据x从小到大排
}
priority_queue<数据类型,vector<数据类型> >
优先队列排序和sort相反,原因:重载运算符的作用,把 > 定义为 < .
4.优先队列有vis.top()代替了vis.front();其他与队列一样.
题目
problem A :买饭-优先队列
nefu 1537
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct stu{
int num;
int time;
};
bool operator<(const stu &a,const stu &b )
{
if(a.time!=b.time)return a.time>b.time;
else return a.num>b.num;
}
priority_queue<stu,vector<stu> >vis;
/*小的在大的前面平均等待时间就最短*/
int main()
{
int n,time;
double sum=0;
scanf("%d",&n);
int m=n;
for(int i=1;i<=n;i++)
{
scanf("%d",&time);
vis.push({i,time});
}
while(vis.size()>1)
{
printf("%d ",vis.top().num);
int t=--n;
while(t)
{
sum+=vis.top().time;
t--;
}
vis.pop();
}
printf("%d\n",vis.top().num);
printf("%.2lf",sum/m);
return 0;
}
/*如果是三个人时间是 10 11 12
则平均等待时间=10*2+11*1+12*0*/
problem B :合并果子-优先队列
nefu 1688
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
priority_queue<int,vector<int>,greater<int> >vis;
int main()
{
int n,x;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
vis.push(x);
}
ll sum=0;
while(vis.size()>1)
{
int tmp1=vis.top();
vis.pop();
int tmp2=vis.top();
vis.pop();
sum+=tmp1+tmp2;
vis.push(tmp1+tmp2);
}
printf("%lld",sum) ;
return 0;
}
problem C :合成陨石-优先队列
nefu 355
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
priority_queue<int,vector<int>,greater<int> >vis;
/*小的在大的前面,才能是最小的破坏能量值*/
int main()
{
int n,x;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&x);
vis.push(x);
}
ll sum=0;
while(vis.size()>1)
{
int tmp1=vis.top();
vis.pop();
int tmp2=vis.top();
vis.pop();
sum+=tmp1+tmp2;
vis.push(tmp1+tmp2);
}
vis.pop();
printf("%lld\n",sum) ;
}
return 0;
}
problem D :瑞瑞的木板-优先队列
nefu 1691
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> >vis;
/*本质上和和并果子的思路是一样的*/
int main()
{
int n,x;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
vis.push(x);
}
long long int sum=0;
while(vis.size()>1)
{
int tmp1=vis.top();
vis.pop();
int tmp2=vis.top();
vis.pop();
sum+=tmp1+tmp2;
vis.push(tmp1+tmp2);
}
printf("%lld\n",sum) ;
return 0;
}
problem E :堆-优先队列
nefu 1692
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> >vis;
int main()
{
int n,x,a;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x==1)
{scanf("%d",&a);vis.push(a);}
if(x==2)printf("%d\n",vis.top());
if(x==3)vis.pop();
}
return 0;
}
problem F :桐桐的新闻系统-优先队列
nefu 1690
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct stu{
int name;
int time1;
int time2;};/*用time2记录初试时间方便好加减*/
priority_queue<stu,vector<stu> >vis;
bool operator<(const stu &a,const stu &b)
{
if(a.time1!=b.time1)return a.time1>b.time1;
else return a.name>b.name;
}
int main()
{
int n,t,k;
char a[100];
while(1)
{scanf("%s",a);
if(a[0]=='#')break;
else
{scanf("%d%d",&n,&t);
vis.push({n,t,t});
}
}
scanf("%d",&k);
for( int i=0;i<k;i++)
{
stu tmp=vis.top();
printf("%d\n",tmp.name);
vis.pop();
vis.push({tmp.name,(tmp.time1)+(tmp.time2),tmp.time2});
}
return 0;
}
problem G:序列合并-优先队列
nefu 1689
a[1],a[2],a[3];
b[1];b[2];b[3];
最小的三位置肯定从 a[1]+b[1]、 a[1]+b[1]、 a[1]+b[2]、 a[1]+b[3]、 a[2]+b[1]、 a[3]+b[1]中;
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct stu{
int x,y;
ll sum;};
priority_queue<stu,vector<stu> >vis;
bool operator<(const stu &a,const stu &b)
{
return a.sum>b.sum;
}
int main()
{
ll n,a[400000],b[400000];
scanf("%lld",&n);
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
for(int j=0;j<n;j++)
scanf("%lld",&b[j]);
for(int i=0;i<n;i++)
vis.push({0,i,a[0]+b[i]});
for(int i=0;i<n;i++)
{
stu t=vis.top();
printf("%lld\n",t.sum);
vis.pop();
int x=t.x;int y=t.y;
vis.push({x+1,y,a[x+1]+b[y]});
}
return 0;
}