绳子与重物
时间限制: 400 ms
内存限制: 64 MB
有N条绳子编号 0 至 N - 1,每条绳子后面栓了一个重物重量为Wi,绳子的最大负重为Ci。每条绳子或挂在别的绳子下或直接挂在钩子上(编号-1)。如果绳子下所有重物的重量大于绳子的最大负重就会断掉(等于不会断)。依次给出每条绳子的负重Ci、重物的重量Wi以及绳子会挂在之前的哪条绳子的下面,问最多挂多少个绳子而不会出现绳子断掉的情况。
例如下图:
5, 2, -1
3, 3, 0
6, 1, -1
3, 1, 0
3, 2, 3
挂到第4个时会有绳子断掉,所以输出3。
输入格式:
第1行:1个数N,表示绳子的数量(1 <= N <= 50000)。
第2 - N+1行:每行3个数,Ci, Wi, Pi。Ci表示最大负重,Wi表示重物的重量,Pi表示挂在哪个绳子上,如果直接挂在钩子上则Pi = -1(1 <= Ci <= 10^9,1 <= Wi <= 10^9,-1 <= Pi <= N - 2)。
输出格式:
输出1个数,最多挂到第几个绳子,不会出现绳子断掉的情况。
输入样例:
1 2 3 4 5 6
| 5 5 2 -1 3 3 0 6 1 -1 3 1 0 3 2 3
|
输出样例:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <stdio.h> #include <stdlib.h>
struct node { int c, w, p, fa; long long sum; };
struct node *a;
int find(int n) { int root = n, curr = n, temp; while(a[root].fa != root) root = a[root].fa; while(curr != root) { temp = a[curr].fa; a[curr].fa = root; curr = temp; } return root; }
int main() { int n, ans; scanf("%d", &n);
a = (struct node *)malloc(sizeof(struct node) * n); for(int i = 0; i < n; ++i) { scanf("%d%d%d", &a[i].c, &a[i].w, &a[i].p); a[i].fa = i; a[i].sum = a[i].w; }
ans = n-1; for(int i = n-1; i >= 0; --i) { while(a[i].sum > a[i].c) { a[find(ans)].sum -= a[ans].w; ans--; } a[a[i].p].sum += a[i].sum; if(a[i].p > -1) a[i].fa = a[i].p; }
printf("%d", ans+1); return 0; }
|