51 Nod 1307 绳子与重物
有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
思路: 并查集 每次向上更新 当前绳子的负重 如果超出限制 就退出
1 #include <cstdio> 2 #include <cctype> 3 4 typedef long long LL; 5 6 const int MAXN=50010; 7 8 int n; 9 10 bool flag; 11 12 int w[MAXN],c[MAXN],f[MAXN]; 13 14 LL d[MAXN]; 15 16 inline void read(int&x) { 17 int f=1;register char c=getchar(); 18 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 19 for(;isdigit(c);x=x*10+c-48,c=getchar()); 20 x=x*f; 21 } 22 23 bool find(int p,int v) { 24 if(p==-1) return true; 25 if(d[p]+v>c[p]) return false; 26 d[p]+=v; 27 if(find(f[p],v)) return true; 28 return false; 29 } 30 31 int hh() { 32 read(n); 33 34 for(int fa,i=0; i<n; ++i) { 35 read(c[i]);read(w[i]);read(fa); 36 f[i]=fa; 37 if(!find(i,w[i])) { 38 flag=true; 39 printf("%d\n",i); 40 break; 41 } 42 } 43 if(!flag) printf("%d\n",n); 44 45 return 0; 46 } 47 48 int sb=hh(); 49 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现