思路:
因为问是最少要多少个地方才能安排好所有牛,所以对于牛按照开始时间升序 开始时间一样按结束时间升序
我们考虑把每头牛丢进去,当前这头牛进去的话 把这头牛的开始时间与已经进去的牛的最早结束的时间比较,如果结束时间>最早结束的时间 那么就是一头牛代替另一头牛进去,那么自然所需要的个数就不变,如果开始时间≤最早结束的时间,那么我们需要新开辟一个地方,让这头牛进去。
综上所述 我们是需要一个可以支持自动排序 、插入、删除的数据结构 自然是优先队列了
维护一个以结束时间的小根堆即可
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
int s,e,id;
}a[500005];
struct nodee
{
int e,id;
friend bool operator<(nodee a,nodee b){ ///以结束时间的小根堆
return a.e>b.e;
}
};
bool cmp(node a,node b){
return a.s==b.s?a.e<b.e:a.s<b.s;
}
int ans[500005];
int main(){
ios::sync_with_stdio(0);
int n;
while(cin>>n){
for(int i=1;i<=n;i++) cin>>a[i].s>>a[i].e,a[i].id=i;
sort(a+1,a+1+n,cmp);///对牛的开始和结束时间进行升序
priority_queue<nodee> q;
q.push({a[1].e,1});
ans[a[1].id]=1;
int cnt=1;
for(int i=2;i<=n;i++){
nodee now=q.top();
if(now.e>=a[i].s){///最先结束的时间 ≥ 当前的开始时间 要新加一个
ans[a[i].id]=++cnt;
q.push({a[i].e,cnt});
}
else///一头牛出来 当前这头进去
{
q.pop();
ans[a[i].id]=now.id;///存这头牛进入的编号
q.push({a[i].e,now.id});
}
}
cout<<cnt<<endl;
for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
}
return 0;
}