【Luogu P2859】【YBTOJ】畜栏预定
题目大意:
有 \(n\) 头牛在畜栏中吃草。每个畜栏在同一时间段只能提供给一头牛吃草,所以可能会需要多个畜栏,给出第 \(i\) 头牛开始吃草的时间区间 \([l_i,r_i]\),求需要的最少的畜栏数和每头牛对应的畜栏方案。
正文:
这道题非常简单,只用顺着题目来就行了。
先将牛牛按 \(l\) 排好序。接下来枚举到第 \(i\) 头,先在已有的畜栏里找有没有哪头牛牛吃完了草。如果有,则当前牛子就占它的位置;如果没有,牛子就到新畜栏去。
这个过程当然可以用堆来实现。按照牛子们的 \(r\) 作为 key。
代码:
const int N = 50010;
int n, ans[N], cnt = 1;
struct node
{
int l, r, id;
}a[N];
struct que
{
int id, r;
const bool operator < (const que &b) const
{
return r > b.r;
}
};
priority_queue <que> q;
bool cmp (node a, node b)
{
if (a.l == b.l) return a.r < b.r;
return a.l < b.l;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf ("%d%d", &a[i].l, &a[i].r), a[i].id = i;
sort (a + 1, a + 1 + n, cmp);
q.push((que){1, a[1].r});
ans[a[1].id] = 1;
for (int i = 2; i <= n; i++)
{
que t = q.top();
if (t.r >= a[i].l)
{
cnt++;
ans[a[i].id] = cnt;
q.push((que){cnt, a[i].r}) ;
}
else
{
q.pop();
ans[a[i].id] = t.id;
q.push((que){t.id, a[i].r});
}
}
printf ("%d\n", cnt);
for (int i = 1; i <= n; i++)
printf ("%d\n", ans[i]);
}