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;
}
posted @ 2025-07-07 17:23  dingchenjun  阅读(3)  评论(1)    收藏  举报