要用dp来求解应该是可以看出的。
但是状态该怎么设呢?
f[u]表示构造完u的子树中的叶子节点后,u节点的最大值吗?
差不多这个意思,只不过此题不能直接用f[u]来表示u节点的最大值,不然的话,我们不能得到叶子节点的f值了。即,边界值不能得到。
所以设:
f[u]表示u的子树中的叶子节点构造完成后,u节点答案最大是第几大。
(设整棵树有k个叶子节点,指k个叶子节点里的第几大)
最后将输出转化一下即可。
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,u,k;
int du[N],pd[N],f[N];
int cnt,head[N];
struct edge{int next,to;}e[N<<1];
inline void add(int u,int v)
{
cnt++;
e[cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void dfs(int u)
{
f[u]=1;
bool jay=false;
int sum=0,minn=n;
for (register int i=head[u]; i; i=e[i].next)
{
jay=true;
dfs(e[i].to);
sum+=f[e[i].to];
minn=min(minn,f[e[i].to]);
}
if (!jay) return;
if (!pd[u]) f[u]=sum;
else f[u]=minn;
}
int main(){
scanf("%d",&n);
for (register int i=1; i<=n; ++i) scanf("%d",&pd[i]);
for (register int i=2; i<=n; ++i)
{
scanf("%d",&u);
add(u,i);
du[u]++; du[i]++;
}
for (register int i=2; i<=n; ++i) if (du[i]==1) k++;
dfs(1);
printf("%d\n",k-f[1]+1);
return 0;
}