POJ 3190 Stall Reservations 优先队列

Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A…B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows.

Help FJ by determining:
The minimum number of stalls required in the barn so that each cow can have her private milking period
An assignment of cows to these stalls over time
Many answers are correct for each test dataset; a program will grade your answer.
Input
Line 1: A single integer, N

Lines 2…N+1: Line i+1 describes cow i’s milking interval with two space-separated integers.
Output
Line 1: The minimum number of stalls the barn must have.

Lines 2…N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.
SampleInput
5
1 10
2 4
3 6
5 8
4 7
SampleOutput
4
1
2
3
2
4

题意:给出n头牛的产奶时间段(s,t) 两头牛不能共用一个牛棚,问最少可以安排多少个牛棚
思路:先以开始时间从小到大排序贪心,之后优先队列维护一个结束时间较早的各个牛的时间段,如果存在某一个优先队列时间段的结束时间小于数组中的开始时间,则该两头牛共属一个牛棚,否则需要再开另一个牛棚。

#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;
const int N = 50005;

int ans[N];

struct node
{
    int s,t;
    int id;///记录位置

    friend bool operator < (const node &a,const node &b)
    {
        if(a.t==b.t)
            return a.s < b.s;///优先队列中以结束时间升序排列,最小留在堆顶
        return a.t > b.t;
    }

} a[N];

bool cmp(node a,node b)///数组中以开始时间升序排序
{
    if(a.s!=b.s)
        return a.s < b.s;
    return a.t < b.t;
}

int main()
{
    int n;
    ios::sync_with_stdio(false);

    while(cin >> n)
    {
        for(int i=1; i<=n; i++)
        {
            cin >> a[i].s >> a[i].t;
            a[i].id=i;
        }

        sort(a+1,a+1+n,cmp);

        int res=1;

        priority_queue<node>que;

        que.push(a[1]);///先压入第一个数
        ans[a[1].id]=1;

        for(int i=2; i<=n; i++)
        {
            if(!que.empty()&&que.top().t<a[i].s)///如果堆顶的结束时间小于当前这头牛的开始时间则在不同时间可以共用一个牛棚
            {
                ans[a[i].id]=ans[que.top().id];///记录答案
                que.pop();
            }
            else
            {
                res++;///不满足的话就需要另一个牛棚 答案加一
                ans[a[i].id]=res;
            }
            que.push(a[i]);
        }

        cout << res << endl;

        for(int i=1; i<=n; i++)
            cout << ans[i] << endl;
    }

    return 0;
}

总结:当时没写出来是不知道优先队列里应该去怎样使用,答案如何记录,其实只要利用一开始数组里的下标,去作为记录答案的下标就可以了

发布了54 篇原创文章 · 获赞 0 · 访问量 1233

猜你喜欢

转载自blog.csdn.net/weixin_44144278/article/details/98904054