CF1153D Serval and Rooted Tree

要用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;
}
//f[u]:u的子树中的叶子节点构造完成后,u节点答案最大是第几大
//(设整棵树有k个叶子节点,指k个叶子节点里的第几大) 
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值