这道题的关键在于叶节点。最后根节点的大小只可能等于其中一个叶节点,而每个子树的父节点的值也都是从叶节点得来的,相当于一个传递过程。
因此令dp[node]叶节点中的第几大的数,则若结点是max,则当然是选取min(dp[node],dp[temp]),(例如最大的叶节点最大,所以dp[node] = 1;若结点是min,假如传到左边是第四大右边第五大,那么合并后相当于取第九大,即dp[node]+=dp[temp].
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define mem(a) memset(a,0,sizeof(a))
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 3e5+10;
using namespace std;
int l;//叶节点
int a[maxn],dp[maxn];
vector<int>v[maxn];
void dfs(int node)
{
if(v[node].size() == 0)
{
dp[node] = 1;
l++;
return;
}
if(a[node])dp[node] = inf;
else dp[node] = 0;
for(int i = 0;i < (int)v[node].size();++i)
{
int temp = v[node][i];
dfs(temp);
if(a[node])dp[node] = min(dp[node],dp[temp]);
else dp[node]+=dp[temp];
}
}
int main(){
int n;
sd(n);
mem(a);
for(int i = 1;i <= n;i++)cin>>a[i];
for(int i = 2;i <= n;i++)
{
int temp;
sd(temp);
v[temp].push_back(i);
}
l = 0;
dfs(1);
cout<<l - dp[1] + 1<<endl;
return 0;
}