建筑抢修 BZOJ 1029

建筑抢修

【问题描述】

小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。

【输入格式】

第一行是一个整数N接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。

【输出格式】

输出一个整数S,表示最多可以抢修S个建筑.

【样例输入】

4
100 200
200 1300
1000 1250
2000 3200

【样例输出】

3

【数据范围】

N < 150,000,T1 < T2 < maxlongint


题解:

先按T2排序,按顺序枚举

贪心考虑,如果能在T2内维修好就加入左偏树(大根堆)

否则考虑与堆顶的关系

如果不维修堆顶而维修当前建筑使用时间更少,就将堆顶弹出加入当前建筑

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 inline int Get()
 9 {
10     int x;
11     char c;
12     while((c = getchar()) < '0' || c > '9');
13     x = c - '0';
14     while((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
15     return x;
16 }
17 const int me = 1000233;
18 struct building
19 {
20     int x, y;
21 }a[me];
22 int n, rt, num;
23 int dis[me], lc[me], rc[me];
24 inline bool rule(const building &a, const building &b)
25 {
26     if(a.y != b.y) return a.y < b.y;
27     return a.x < b.x;
28 }
29 int Marge(int x, int y)
30 {
31     if(!x) return y;
32     if(!y) return x;
33     if(a[x].x < a[y].x) swap(x, y);
34     rc[x] = Marge(rc[x], y);
35     if(dis[lc[x]] < dis[rc[x]]) swap(lc[x], rc[x]);
36     if(!rc[x]) dis[x] = 0;
37     else dis[x] = dis[rc[x]] + 1;
38     return x;
39 }
40 int main()
41 {
42     n = Get();
43     for(int i = 1; i <= n; ++i)
44     {
45         a[i].x = Get();
46         a[i].y = Get();
47     }
48     sort(a + 1, a + 1 + n, rule);
49     int ti = 0;
50     for(int i = 1; i <= n; ++i)
51     {
52         if(ti + a[i].x <= a[i].y)
53         {
54             rt = Marge(rt, i);
55             ti += a[i].x;
56             ++num;
57         }
58         else
59         {
60             if(!rt) continue;
61             int c = ti - a[rt].x + a[i].x;
62             if(c <= a[i].y && a[i].x < a[rt].x)
63             {
64                 int a = lc[rt], b = rc[rt];
65                 rt = Marge(a, b);
66                 rt = Marge(rt, i);
67                 ti = c;
68             }
69         }
70     }
71     printf("%d", num);
72 }
posted @ 2017-03-02 19:50  草根柴鸡  阅读(157)  评论(0编辑  收藏  举报