第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個數,最多掛到第幾個繩子,不會出現繩子斷掉的情況。
5 5 2 -1 3 3 0 6 1 -1 3 1 0 3 2 3
3
先根據P[i] 建邊.
然後枚舉答案-.-然後dfs判斷。
代碼:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int c[50100],w[50100],p[50100];
int m;
bool fafe;
vector<int> V[50100];
int dfs(int x)
{
if (!fafe) return 0;
int he=w[x];
for (int i=0;i<V[x].size();i++)
{
if (V[x][i]<m)
he+=dfs(V[x][i]);
}
if (he>c[x])
fafe=false;
return he;
}
bool pan()
{
fafe=true;
for (int i=0;i<m;i++)
{
if (p[i]==-1)
dfs(i);
if (!fafe) break;
}
return fafe;
}
int main()
{
int n;cin>>n;
for (int i=0;i<n;i++)
{
cin>>c[i]>>w[i]>>p[i];
if (p[i]!=-1)
V[p[i]].push_back(i);
}
int l=1,r=n,ans=0;
while (l<=r)
{
m=(l+r)>>1;
if (pan())
{
ans=m;
l=m+1;
}
else
r=m-1;
}
cout<<ans<<endl;
return 0;
}