【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]);
}
posted @ 2020-12-24 16:07  Jayun  阅读(109)  评论(0编辑  收藏  举报