对于每一个节点,其权值可以任意大,一个节点的子树(不包括该节点)的权值和是多少并不影响,因为不足的可以通过该节点来加上。
对于节点 x x x,其颜色为黑色,设其子树中黑色的和为 s u m h e i x sum_{hei_{x}} sumheix
要使得其子树中白色的和尽量小,设白色的和为 s u m b a i x sum_{bai_{x}} sumbaix
如果 x x x选择为黑色之后,则对于其每个子节点 s o n x son_x sonx
有以下两种情况二选一:
s u m h e i x + = s u m h e i s o n x , s u m b a i x + = s u m b a i s o n x sum_{hei_{x}}+=sum_{hei_{son_x}},sum_{bai_{x}}+=sum_{bai_{son_x}} sumheix+=sumheisonx,sumbaix+=sumbaisonx
s u m h e i x + = s u m b a i s o n x , s u m b a i x + = s u m h e i s o n x sum_{hei_{x}}+=sum_{bai_{son_x}},sum_{bai_{x}}+=sum_{hei_{son_x}} sumheix+=sumbaisonx,sumbaix+=sumheisonx
直接在树上进行背包就行了
复杂度 O ( n x ) O(nx) O(nx)
#include<bits/stdc++.h>
using namespace std;
#define f1(a,b,c) for(int c=a;c<=b;c++)
#define f2(a,b,c) for(int c=a;c>=b;c--)
#define f3(a,b,c) for(int c=a;c;c=b)
#define so1(a,n) sort(a+1,a+n+1,mycmp);
#define so2(a,n) sort(a+1,a+n+1);
#define ll long long
#define itn int
#define ubt int
#define mp make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
const int twx=5e3+100;
const int inf=0x3f3f3f3f;
ll read()
{
ll sum=0;
ll flag=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
{
flag=-1;
}
c=getchar();
}
while(c>='0'&&c<='9')
{
sum=((sum*10)+c-'0');
c=getchar();
}
return sum*flag;
}
int n;
int xs[twx];
struct LV
{
int y;
int Next;
}a[twx];
int Link[twx];
int len;
int asd[twx];
int qwe[2][twx];
void Insert(int x,int y)
{
a[++len].y=y;
a[len].Next=Link[x];
Link[x]=len;
}
void dfs(int x)
{
f3(Link[x],a[i].Next,i)
{
int y=a[i].y;
dfs(y);
}
memset(qwe[0],0x3f,sizeof qwe[0]);
int tmp=0;
qwe[tmp][0]=0;
f3(Link[x],a[i].Next,i)
{
int y=a[i].y;
tmp^=1;
memset(qwe[tmp],0x3f,sizeof qwe[tmp]);
f1(0,xs[x],j)
{
if(j-xs[y]>=0)
{
qwe[tmp][j]=min(qwe[tmp][j],qwe[tmp^1][j-xs[y]]+asd[y]);
}
if(j-asd[y]>=0)
{
qwe[tmp][j]=min(qwe[tmp][j],qwe[tmp^1][j-asd[y]]+xs[y]);
}
}
}
f1(0,xs[x],i)
{
asd[x]=min(asd[x],qwe[tmp][i]);
}
}
void init()
{
n=read();
f1(2,n,i)
{
int p=read();
Insert(p,i);
}
f1(1,n,i)
{
xs[i]=read();
}
memset(asd,0x3f,sizeof asd);
dfs(1);
if(asd[1]!=inf)
{
puts("POSSIBLE");
}
else
{
puts("IMPOSSIBLE");
}
}
int main()
{
init();
return 0;
}