【贪心+优先队列】POJ3190-Stall Reservations

【题目大意】

给出每个奶牛挤奶的时间,同一时间同一畜栏内不会有两头奶牛挤奶,问至少要多少个畜栏。

【思路】

将奶牛按照挤奶开始的时间进行升序排序,再用一个小顶堆维护每一个畜栏当前的挤奶结束时间。对于当前的奶牛,如果所有畜栏最小的结束时间都大于它的开始时间,则新开一个畜栏,将结束时间设为当前奶牛的结束时间,加入优先队列;如果能够用结束时间最小的畜栏了,则将该畜栏的结束时间更新为当前奶牛的结束时间。

最后按照输入顺序输出结果。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int MAXN=50000+50;
 7 typedef pair<int,int> p;
 8 /*first表示结束时间,second表示畜栏编号*/
 9 struct node
10 {
11     int a,b,inno,no;
12     bool operator < (const node & x) const
13     {
14         return a<x.a;
15     }
16 }cow[MAXN];
17 int n,num=0;
18 
19 void submain()
20 {
21     sort(cow,cow+n);
22     priority_queue<p,vector<p>,greater<p> > que;
23     /*建立一个以结束时间为关键字的小顶堆*/ 
24     
25     num++;
26     que.push(p(cow[0].b,num));
27     cow[0].no=num;
28     for (int i=1;i<n;i++)
29     {
30         p now=que.top();
31         if (cow[i].a<=now.first)
32         {
33             /*如果当前的畜栏不能共用,那么新开一个畜栏*/
34             num++;
35             que.push(p(cow[i].b,num));
36             cow[i].no=num;
37         }
38         else
39         {
40             /*如果能够共用,那么久更新当前畜栏的结束时间*/
41             que.pop();
42             que.push(p(cow[i].b,now.second));
43             cow[i].no=now.second;
44         }
45     }
46 }
47 
48 void print()
49 {
50     cout<<num<<endl;
51     int out[MAXN];
52     for (int i=0;i<n;i++) out[cow[i].inno]=cow[i].no;
53     for (int i=0;i<n;i++) cout<<out[i]<<endl;
54 }
55 
56 int main()
57 {
58     scanf("%d",&n);
59     for (int i=0;i<n;i++) 
60     {
61         scanf("%d%d",&cow[i].a,&cow[i].b);
62         cow[i].inno=i;
63         /*由于输出是按照输入顺序的,所以排序前必须要保留原来的编号*/ 
64     }
65     submain();
66     print();
67     return 0;
68 }
posted @ 2015-08-18 11:47  iiyiyi  阅读(477)  评论(0编辑  收藏  举报