Serval and Rooted Tree CodeForces - 1153D(树形dp)

Now Serval is a junior high school student in Japari Middle School, and he is still thrilled on math as before.

As a talented boy in mathematics, he likes to play with numbers. This time, he wants to play with numbers on a rooted tree.

A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a node vv is the last different from vv vertex on the path from the root to the vertex vv. Children of vertex vv are all nodes for which vv is the parent. A vertex is a leaf if it has no children.

The rooted tree Serval owns has nn nodes, node 11 is the root. Serval will write some numbers into all nodes of the tree. However, there are some restrictions. Each of the nodes except leaves has an operation maxmax or minmin written in it, indicating that the number in this node should be equal to the maximum or minimum of all the numbers in its sons, respectively.

Assume that there are kk leaves in the tree. Serval wants to put integers 1,2,…,k1,2,…,k to the kk leaves (each number should be used exactly once). He loves large numbers, so he wants to maximize the number in the root. As his best friend, can you help him?

Input
The first line contains an integer nn (2≤n≤3⋅1052≤n≤3⋅105), the size of the tree.

The second line contains nn integers, the ii-th of them represents the operation in the node ii. 00 represents minmin and 11 represents maxmax. If the node is a leaf, there is still a number of 00 or 11, but you can ignore it.

The third line contains n−1n−1 integers f2,f3,…,fnf2,f3,…,fn (1≤fi≤i−11≤fi≤i−1), where fifi represents the parent of the node ii.

Output
Output one integer — the maximum possible number in the root of the tree.

Examples
Input
6
1 0 1 1 0 1
1 2 2 2 2
Output
1
Input
5
1 0 1 0 1
1 1 1 1
Output
4
Input
8
1 0 0 1 0 1 1 0
1 1 2 2 3 3 3
Output
4
Input
9
1 1 0 0 1 0 1 0 1
1 1 2 2 3 3 4 4
Output
5
Note
Pictures below explain the examples. The numbers written in the middle of the nodes are their indices, and the numbers written on the top are the numbers written in the nodes.

In the first example, no matter how you arrange the numbers, the answer is 11.
在这里插入图片描述

In the second example, no matter how you arrange the numbers, the answer is 44.
在这里插入图片描述

In the third example, one of the best solution to achieve 44 is to arrange 44 and 55 to nodes 44 and 55.
在这里插入图片描述

In the fourth example, the best solution is to arrange 55 to node 55.
在这里插入图片描述
很新奇的一道题目(可能是我太菜了没做过类似的题目)。以后遇到这种1~k的题目,就多想想能否往第k大转换。。
假如说这个节点是取Max,那么他肯定是取它的子节点中第一大的那一个。所以取最大的时候,我们就采取子树中最小的那一个,就是这个节点所要采取的值。即dp[u]=min(dp[u],dp[to]);
假如说这个节点是取Min,那么他肯定是取它的子节点中第sum[v]大的那一个(sum[v]是v的子树节点个数)所以取最小的时候,我们就加上它的子树中的值,即dp[u]+=dp[to];
代码如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

const int maxx=3e5+100;
struct node{
	int to,next;
}e[maxx<<1];
int head[maxx<<1];
int tz[maxx];
int sz[maxx];
int dp[maxx];
int n,tot,cnt;
/*---------事前准备---------*/
inline void init()
{
	memset(head,-1,sizeof(head));
	tot=cnt=0;
}
inline void add(int u,int v)
{
	e[tot].to=v,e[tot].next=head[u],head[u]=tot++;
}
/*-----------树形dp----------*/
inline void dfs(int u,int f)
{
	if(sz[u]==1) 
	{
		dp[u]=1;
		cnt++;
		return ;
	}
	dp[u]=(tz[u]==1?inf:0);//dp[u]代表的是第u个结点采取第dp[u]大的点。
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		int to=e[i].to;
		if(to==f) continue;
		dfs(to,u);
		if(tz[u]) dp[u]=min(dp[u],dp[to]);
		else dp[u]+=dp[to];//状态转移方程要仔细理解,这是这个问题转化的重点。
	}
}
int main()
{
	int x;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++) scanf("%d",&tz[i]);
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&x);
		add(i,x);
		add(x,i);
		sz[x]++;sz[i]++;
	}
	dfs(1,0);
	cout<<cnt-dp[1]+1<<endl;//输出最后结果
	return 0;
}

dp总是这么吸引人但是又在折磨人
努力加油a啊,(o)/~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值