priority-queue和优先队列
P7913
让我们先忽略廊桥数量的限制来安排航班。我们维护一个空闲的廊桥队列,每到达一架航班,就给它安排编号最小的廊桥供其使用。
现在加上廊桥数量的限制。容易发现刚才的廊桥分配方法直接就帮我们解决了廊桥限制的问题:如果当前有 n 个廊桥可供使用,则分配到 n+1 号及以后的廊桥实质上就是分配到远机位了,不需要再做任何额外的处理。
到这里做法就很清晰了:我们按照开头提到的分配方法来安排航班的停靠位置,记录各廊桥停靠的航班数,做一个前缀和,最后枚举分配给某个区的廊桥数,算出各情况下两区实际使用廊桥的航班数总和,即可解决本题。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+100;
int n,m1,m2;
struct dd {
int l,r;
}a[MAXN],b[MAXN];
bool cmp(dd x, dd y) {
return x.l<y.l;
}
struct dv {
int x;
bool operator <(const dv &i) const {
return a[x].r>a[i.x].r;
}
};
struct du {
int x;
bool operator <(const du &i) const {
return b[x].r>b[i.x].r;
}
};
priority_queue<dv> que1;
priority_queue<du> que2;
priority_queue <int, vector <int>, greater <int> > q;
int ans[MAXN],sum1[MAXN],sum2[MAXN];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m1 >> m2;
for (int i=1; i<=m1; i++) {
cin >> a[i].l >> a[i].r;
}
for (int i=1; i<=m2; i++) {
cin >> b[i].l >> b[i].r;
}
sort(a+1,a+m1+1,cmp);
sort(b+1,b+m2+1,cmp);
for (int i=1; i<=n; i++) {
q.push(i);
}
for (int i=1; i<=m1; i++) {
while (!que1.empty() && a[que1.top().x].r<a[i].l) {
q.push(ans[que1.top().x]);
que1.pop();
}
if (!q.empty()){
que1.push({i});
ans[i]=q.top();
sum1[q.top()]++;
q.pop();
}
}
for (int i=1; i<=m1; i++) {
ans[i]=0;
}
while (!q.empty()) {
q.pop();
}
for (int i=1; i<=n; i++) {
q.push(i);
}
for (int i=1; i<=m2; i++) {
while (!que2.empty() && b[que2.top().x].r<b[i].l) {
q.push(ans[que2.top().x]);
que2.pop();
}
if (!q.empty()){
que2.push({i});
ans[i]=q.top();
sum2[q.top()]++;
q.pop();
}
}
for (int i=1; i<=n; i++) {
sum1[i]+=sum1[i-1];
sum2[i]+=sum2[i-1];
}
int sum=0;
for (int i=0; i<=n; i++) {
sum=max(sum,sum1[i]+sum2[n-i]);
}
cout <<sum;
return 0;
}
P11289
月赛水题
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> PII;
const int N=200010;
int n,m;
priority_queue<int,vector<int>,greater<int> > heap;
priority_queue<PII,vector<PII>,greater<PII> > q;
vector<int> v[N];
struct node{
LL s,t;
int num;
}a[N];
bool cmp(node X,node Y)
{
return X.t<Y.t;
}
int main()
{
//freopen("print2.in","r",stdin);
//freopen("print.ans","w",stdout);
cin.tie(0)->sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].s>>a[i].t;
a[i].num=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=m;i++) heap.push(i);
for(int i=1;i<=n;i++)
{
while(q.size())
{
PII t=q.top();
LL tim=t.first,num=t.second;
if(tim<=a[i].t)
{
q.pop();
heap.push(num);
}
else break;
}
if(heap.size())
{
int num=heap.top();
heap.pop();
q.push({a[i].s+a[i].t,num});
v[num].push_back(a[i].num);
}
else
{
PII t=q.top();
q.pop();
LL tim=t.first,num=t.second;
q.push({tim+a[i].s,num});
v[num].push_back(a[i].num);
}
}
for(int i=1;i<=m;i++)
{
int sum=v[i].size();
cout<<sum;
sort(v[i].begin(),v[i].end());
for(int j=0;j<sum;j++) cout<<" "<<v[i][j];
cout<<"\n";
}
return 0;
}