有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。
Input
第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)。
Output
输出1个数,最多挂到第几个绳子,不会出现绳子断掉的情况。
Input示例
5 5 2 -1 3 3 0 6 1 -1 3 1 0 3 2 3
Output示例
3
李陶冶
(题目提供者)
#include
#define N 100000
using namespace std;
struct node{
int w,p,c,sum;
}x[N];
int f[N*6];
int find(int k){
if (k==f[k]) return f[k];
else{
f[k]=find(f[k]);
return f[k];
}
}
int main(){
int n,i;
scanf("%d",&n);
for (i=1;i<=n;i++){
scanf("%d%d%d",&x[i].c,&x[i].w,&x[i].p);
x[i].p++;
x[i].sum=x[i].w;
f[i]=i;
}
long long ans=n;
for (int i=n;i>=1;i--){
while (x[i].sum>x[i].c){
int k=find(ans);
x[k].sum-=x[ans].w;
ans--;
}
x[x[i].p].sum+=x[i].sum;
f[i]=x[i].p;
}
printf("%I64d\n",ans);
return 0;
}