Codeforces1153——D. Serval and Rooted Tree(思维好题+dfs+贪心)

简介: Codeforces1153——D. Serval and Rooted Tree(思维好题+dfs+贪心)

原题链接

D. Serval and Rooted Tree

time limit per test2 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard 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 v is the last different from v vertex on the path from the root to the vertex v. Children of vertex v are all nodes for which v is the parent. A vertex is a leaf if it has no children.


The rooted tree Serval owns has n nodes, node 1 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 max or min 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 k leaves in the tree. Serval wants to put integers 1,2,…,k to the k 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 n (2≤n≤3⋅105), the size of the tree.


The second line contains n integers, the i-th of them represents the operation in the node i. 0 represents min and 1 represents max. If the node is a leaf, there is still a number of 0 or 1, but you can ignore it.


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


Output

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


Examples

inputCopy

6

1 0 1 1 0 1

1 2 2 2 2

outputCopy

1

inputCopy

5

1 0 1 0 1

1 1 1 1

outputCopy

4

inputCopy

8

1 0 0 1 0 1 1 0

1 1 2 2 3 3 3

outputCopy

4

inputCopy

9

1 1 0 0 1 0 1 0 1

1 1 2 2 3 3 4 4

outputCopy

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 1.


In the second example, no matter how you arrange the numbers, the answer is 4.


In the third example, one of the best solution to achieve 4 is to arrange 4 and 5 to nodes 4 and 5.


In the fourth example, the best solution is to arrange 5 to node 5.

题意:

20200401134307494.png

思路:

是一个有idea但是没有写出来的题。

首先,贪心的考虑,假设对于非叶子节点x xx:

1.当该节点的操作为m a x maxmax时:该点的值为叶子节点的最大值。

2.当该节点的操作为m i n minmin时:该点要尽可能的取到最大值。

这时候要尽可能的把大的放到叶子节点数量少的点。

20200401134307494.png

比如这个图,假设1 , 2 , 3 , 4 1,2,3,41,2,3,4节点的值都是m i n minmin,那么考虑如何分配是最优的:

就是把大的尽可能分给12 , 13 12,1312,13。

实现起来就很思维了。

数组d [ i ] d[i]d[i]维护的是以i ii为根节点的子树中叶子节点的数值排名d [ i ] d[i]d[i]大的数值。

比如该节点x xx下有6个叶子节点,d [ x ] = 2 d[x]=2d[x]=2,表示这个节点最大可以是6-2+1=5,也就是第二大的数。

下面就是分类讨论了:

1.当前节点x xx为叶子节点,d [ x ] = 1 d[x]=1d[x]=1

2.当前节点x xx的值为m i n minmin,d [ x ] = ∑ y = s o n x d y d[x]=\sum_{y=son_{x}}^{}{d_{y}}d[x]=∑

y=sonxdy3.当前节点的值为m a x maxmax,d [ x ] = m i n ( d [ y ] ) d[x]=min(d[y])d[x]=min(d[y])

对于分类讨论的内容可以画图理解。

答案为叶子节点个数+1-d [ 1 ] d[1]d[1]

代码:

///#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
typedef pair<double, double>PDD;
#define I_int ll
inline ll read(){ll x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a, ll b, ll p){ll res = 1;while(b){if(b & 1)res = res * a % p;a = a * a % p;b >>= 1;}return res;}
const int inf = 0x3f3f3f3f;
#define PI acos(-1)
const double eps = 1e-8;
const int maxn = 3e5 + 7,mod=1000000007;
int d[maxn],a[maxn];
vector<int>g[maxn];
int n,cnt=0;
void dfs(int u){
  if(!g[u].size()){
    d[u]=1;
    cnt++;
    return ;
  }
  if(a[u]) d[u]=n;
  else d[u]=0;
  for(int t:g[u]){
    dfs(t);
    if(a[u]) d[u]=min(d[u],d[t]);
    else d[u]+=d[t];
  }
}
int main(){
  n=read;
  rep(i,1,n) a[i]=read;
  rep(i,2,n){
    int x=read;
    g[x].push_back(i);
  }
  dfs(1);
  cout<<cnt+1-d[1]<<endl;
  return 0;
}

参考


目录
相关文章
|
4天前
【洛谷 P1219】[USACO1.5]八皇后 Checker Challenge 题解(深度优先搜索+回溯法)
**USACO1.5八皇后挑战**是关于在$n\times n$棋盘上放置棋子的,确保每行、每列及两条主对角线上各有一个且仅有一个棋子。给定$6$作为输入,输出前$3$个解及解的总数。例如,对于$6\times6$棋盘,正确输出应包括解的序列和总数。代码使用DFS解决,通过跟踪对角线占用状态避免冲突。当找到所有解时,显示前三个并计数。样例输入$6$产生输出为解的前三个排列和总数$4$。
10 0
|
11天前
|
算法
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
|
1月前
|
人工智能
倍增LCA受到启发的一题
倍增LCA受到启发的一题
17 0
|
8月前
|
程序员 定位技术 C++
[蓝桥杯] 双指针、BFS和DFS与图论问题
本篇文章针对蓝桥杯比赛的考点,列出双指针、BFS和DFS与图论的相关习题以及知识点的解释。希望本篇文章会对你有所帮助。
57 0
|
10月前
|
算法 C++
dfs经典例题(故事中的题解)
dfs经典例题(故事中的题解)
68 0
|
算法 索引
LeetCode算法小抄-- N 叉树 和 洗牌算法
LeetCode算法小抄-- N 叉树 和 洗牌算法
|
算法
从三道leetcode掌握深度优先搜索(DFS)
前言 无论在算法面试还是刷题中,深度优先搜索(DFS)和广度优先搜索(BFS)都是一个绕不过去的坎。不同于数组的从左至右遍历,循环常用于一维数据结构的遍历。而DFS和BFS则常用于多维数据结构的遍历,最常见的莫过于嵌套结构的多叉树了。
|
算法
算法刷题第七天:广度优先搜索 / 深度优先搜索--1
我们把方法二中的栈改为队列,每次从队首取出土地,并将接下来想要遍历的土地放在队尾,就实现了广度优先搜索算法。
81 0
算法刷题第七天:广度优先搜索 / 深度优先搜索--1
|
算法
算法刷题第九天:广度优先搜索 / 深度优先搜索--3
需要额外的 dis 数组记录每个新鲜橘子被腐烂的最短时间,大小为 O(nm),且广度优先搜索中队列里存放的状态最多不会超过nm 个,最多需要 O(nm) 的空间,所以最后的空间复杂度为 O(nm)。
71 0
算法刷题第九天:广度优先搜索 / 深度优先搜索--3
|
存储 算法
算法刷题第八天:广度优先搜索 / 深度优先搜索--2
空间复杂度:O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点个数。空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的最大高度,最坏情况下,二叉树的高度等于节点数。
121 0
算法刷题第八天:广度优先搜索 / 深度优先搜索--2