如题:http://poj.org/problem?id=3190
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 3380 | Accepted: 1207 | Special Judge |
Description
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
Input
Lines 2..N+1: Line i+1 describes cow i's milking interval with two space-separated integers.
Output
Lines 2..N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.
Sample Input
5 1 10 2 4 3 6 5 8 4 7
Sample Output
4 1 2 3 2 4
Hint
Here's a graphical schedule for this output:
Time 1 2 3 4 5 6 7 8 9 10 Stall 1 c1>>>>>>>>>>>>>>>>>>>>>>>>>>> Stall 2 .. c2>>>>>> c4>>>>>>>>> .. .. Stall 3 .. .. c3>>>>>>>>> .. .. .. .. Stall 4 .. .. .. c5>>>>>>>>> .. .. ..Other outputs using the same number of stalls are possible.
Source
题目很容易就能懂,给出几个区间,不能重叠,问需要的最小stall。
首先对输入数据排序,按左端点小->大,然后开始遍历,每次插入一个后,用优先队列维护。维护的是右端点最小。
不难发现,每次插入最左端,那么只用判断右端点,每次选择右端点最小的那个插入,最终方案最优,如果最小的那个都有重叠区间,那么stall的数量只能再+1了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
#define min(a,b)(a< b?a:b)
struct node
{
int l,r;
int pos;
};
node Line[50005];
int stall[50005];
int cmp(node &a,node &b)
{
if(a.l!=b.l)
return a.l<b.l;
return a.r<b.r;
}
class cmp1
{
public:
bool operator()(node&a,node&b)
{
return a.r>b.r;
}
};
int main()
{
// freopen("C:\\1.txt","r",stdin);
int N,num=1;
scanf("%d",&N);
int i;
for(i=0;i<N;i++)
{
scanf("%d%d",&Line[i].l,&Line[i].r);
Line[i].pos=i+1;
}
sort(Line,Line+N,cmp);
priority_queue<node,vector<node>,cmp1>que;
que.push(Line[0]);
stall[Line[0].pos]=1;
i=1;
while(i<N)
{
node p=que.top();
if(Line[i].l>p.r)
{
que.pop();
stall[Line[i].pos]=stall[p.pos];
}
else if(Line[i].l<=p.r)
{
num++;
stall[Line[i].pos]=num;
}
que.push(Line[i]);
i++;
}
printf("%d\n",num);
for(i=1;i<=N;i++)
printf("%d\n",stall[i]);
}