贪心+优先队列
引用他人的题解:将奶牛按照挤奶开始的时间进行升序排序,再用一个小顶堆维护每一个畜栏当前的挤奶结束时间。对于当前的奶牛,如果所有畜栏最小的结束时间都大于它的开始时间,则新开一个畜栏,将结束时间设为当前奶牛的结束时间,加入优先队列;如果能够用结束时间最小的畜栏了,则将该畜栏的结束时间更新为当前奶牛的结束时间。
来源:https://www.cnblogs.com/iiyiyi/p/4739003.html
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef pair<int,int> p;
const int maxn = 5e4 + 5;
int order[maxn];
priority_queue<p,vector<p>,greater<p> > q;
struct node
{
int l, r, id;
bool operator < (const node & x) const {
return l < x.l;
}
} cow[maxn];
int main()
{
int n; scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d%d",&cow[i].l,&cow[i].r);
cow[i].id = i;
}
sort(cow+1,cow+n+1);
int num = 1;
q.push(p(cow[1].r,num));
order[cow[1].id] = 1;
for(int i = 2; i <= n; i++){
if(cow[i].l > q.top().first){
order[cow[i].id] = q.top().second;
q.pop();
q.push(p(cow[i].r,order[cow[i].id]));
}
else{
order[cow[i].id] = ++num;
q.push(p(cow[i].r,num));
}
}
printf("%d\n",num);
for(int i = 1; i <= n; i++){
printf("%d\n",order[i]);
}
return 0;
}