有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
//感觉这题难的是存图,明白后,二分,dfs检验一下即可

1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MOD 998244353 4 #define INF 0x3f3f3f3f3f3f3f3f 5 #define LL long long 6 #define MX 50005 7 struct Node 8 { 9 int dex; //编号 10 int c, w; //绳子承重,重量 11 }; 12 13 int n, ok, mid; 14 vector<Node> G[MX]; //挂在几号点 15 16 int dfs(int x) 17 { 18 int tot=0; 19 for (int i=0;i<G[x].size();i++) 20 { 21 if (G[x][i].dex<=mid) 22 { 23 tot+=G[x][i].w; 24 int temp = dfs(G[x][i].dex); 25 if (G[x][i].w+temp>G[x][i].c) ok=0; 26 tot+=temp; 27 } 28 } 29 return tot; 30 } 31 32 int main() 33 { 34 while(scanf("%d",&n)!=EOF) 35 { 36 for (int i=0;i<=n;i++) 37 G[i].clear(); 38 for (int i=1;i<=n;i++) 39 { 40 int c,w,g; 41 scanf("%d%d%d",&c,&w,&g); 42 g++; 43 G[g].push_back((Node){i,c,w}); 44 } 45 int ans=0, l=1, r=n; 46 while (l<=r) 47 { 48 mid = (l+r)>>1; 49 ok=1; dfs(0); 50 if (ok) l = mid+1, ans = mid; 51 else r = mid-1; 52 } 53 printf("%d ",ans); 54 } 55 return 0; 56 }