Codeforces1153D-Serval and Rooted Tree(樹形dp)

原題鏈接:http://codeforces.com/problemset/problem/1153/D

題目原文:

D. Serval and Rooted Tree

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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

Copy

6
1 0 1 1 0 1
1 2 2 2 2

output

Copy

1

input

Copy

5
1 0 1 0 1
1 1 1 1

output

Copy

4

input

Copy

8
1 0 0 1 0 1 1 0
1 1 2 2 3 3 3

output

Copy

4

input

Copy

9
1 1 0 0 1 0 1 0 1
1 1 2 2 3 3 4 4

output

Copy

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.

題目大意:

        給一棵樹,樹有min/max標記,設葉子節點數量爲k,則讓你分別給每個葉子節點賦[1, k]值 ,通過max/min計算後,使得根1節點的值最大。

解題思路:

        權值是自己任意分配,觀察可以發現,有些節點對根節點的值是沒有貢獻的,那麼可以把問題看成對根節點有貢獻的葉子節點個數。然後我們可以把[1, k]從大到小分配給這些葉子節點。貪心的想:如果根是max,那麼肯定選擇子樹中葉子節點最少的;如果根是min,那麼所有子樹都要考慮了。dp[i] 爲以 i 爲根的子樹葉子節點個數,如果 i 爲 max,dp[i] = min { dp[i], dp[child[i][j]] }, 如果 i 爲 min,dp[i] += dp[i][child[i][j]]; 答案爲葉子節點總個數 all - dp[1] + 1.

AC代碼:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = int(3e5 + 5);
const int INF = 0x3f3f3f3f;

int n;
int o[N]; // operation
vector<int> tree[N];
int dp[N];
int all;

void dfs(int r)
{
	if (tree[r].empty())
	{
		dp[r] = 1;
		all++;
		return;
	}
	if (o[r] == 1) dp[r] = INF;
	else dp[r] = 0;
	int i;
	for (i = 0; i < tree[r].size(); i++)
	{
		dfs(tree[r][i]);
		if (o[r] == 1) dp[r] = min(dp[r], dp[tree[r][i]]);
		else dp[r] += dp[tree[r][i]];
	}
}

int main()
{
	int i;
	while (scanf("%d", &n) != EOF)
	{
		all = 0;
		for (i = 1; i <= n; i++)
		{
			tree[i].clear();
			scanf("%d", &o[i]);
		}
		int f;
		for (i = 2; i <= n; i++)
		{
			scanf("%d", &f);
			tree[f].push_back(i);
		}
		dfs(1);
		printf("%d\n", all - dp[1] + 1);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章