二分枚举,判断挂上x个重物会不会使绳子断裂。
判断时,可以采用dfs的方法,求出每个节点为根节点的子树的点权值和,和最大负重进行比较即可。
#include<bits/stdc++.h>
using namespace std;
const int N=50050;
long long c[N],w[N],sum[N],p[N];
vector<int> vec[N];
void dfs(int x)
{
sum[x]=w[x];
for(int i=0;i<vec[x].size();i++)
{
dfs(vec[x][i]);
sum[x]+=sum[vec[x][i]];
}
}
bool judge(int limit)
{
int i;
for(i=0;i<limit;i++)
vec[i].clear();
for(i=0;i<limit;i++)
{
if(p[i]!=-1)
vec[p[i]].push_back(i);
}
for(i=0;i<limit;i++)
{
if(p[i]==-1)
dfs(i);
if(sum[i]>c[i])
return 0;
}
return 1;
}
int main()
{
int n,lef,rig,mid,i;
while(cin>>n)
{
for(i=0;i<n;i++)
{
scanf("%lld%lld%lld",&c[i],&w[i],&p[i]);
}
lef=0;rig=n;
while(lef<=rig)
{
mid=(lef+rig)>>1;
if(judge(mid))
lef=mid+1;
else
rig=mid-1;
}
printf("%d\n",rig);
}
}