HDU6504 Problem E. Split The Tree【dsu on tree】
Problem E. Split The Tree
Problem Description
You are given a tree with n vertices, numbered from 1 to n. ith vertex has a value wi
We define the weight of a tree as the number of different vertex value in the tree.
If we delete one edge in the tree, the tree will split into two trees. The score is the sum of these two trees’ weights.
We want the know the maximal score we can get if we delete the edge optimally
给出一棵根为\(1\)的树,每个节点有权值,现在断开一条边,把树一分为二,记一棵树的贡献为这棵树里所有节点中不同权值的数量,现在要计算断开边之后两棵树的贡献的和的最大值
现在有一棵子树,为了得到答案,我们只要知道它里面出现过的各个权值有多少个,记原树中各个权值出现的数量是\(cnt[i]\),分开之后的一棵子树的各个权值出现的数量使\(dcnt[i]\),只要出现\(dcnt[i]\ne cnt[i]\ and\ dcnt[i]\ne 0\),对答案的贡献就\(+1\),这个可以\(O(1)\)处理,那么就可以树上启发式合并了
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n,w[MAXN],ret,tmp,cnt[MAXN],dcnt[MAXN],son[MAXN],sz[MAXN],st[MAXN],ed[MAXN],id[MAXN],dfn;
vector<int> G[MAXN];
void dfs(int u){
sz[u] = 1; son[u] = 0;
st[u] = ++dfn; id[dfn] = u;
for(int v : G[u]){
dfs(v);
sz[u] += sz[v];
if(sz[v]>sz[son[u]]) son[u] = v;
}
ed[u] = dfn;
}
void update(int val, int inc){
if(inc==1){
if(!dcnt[val]) tmp++;
dcnt[val]++;
if(dcnt[val]==cnt[val]) tmp--;
}
else{
if(dcnt[val]==cnt[val]) tmp++;
dcnt[val]--;
if(!dcnt[val]) tmp--;
}
}
void search(int u, bool clear){
for(int v : G[u]) if(v!=son[u]) search(v,true);
if(son[u]) search(son[u],false);
for(int v : G[u]) if(v!=son[u]) for(int i = st[v]; i <= ed[v]; i++) update(w[id[i]],1);
update(w[u],1);
ret = max(ret,tmp);
if(clear) for(int i = st[u]; i <= ed[u]; i++) update(w[id[i]],-1);
}
void solve(){
dfn = 0;
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 2; i <= n; i++){
int par; scanf("%d",&par);
G[par].push_back(i);
}
tmp = 0;
for(int i = 1; i <= n; i++){
scanf("%d",&w[i]);
if(!cnt[w[i]]) tmp++;
cnt[w[i]]++;
}
ret = tmp;
dfs(1);
search(1,true);
printf("%d\n",ret);
for(int i = 1; i <= n; i++) cnt[w[i]]--;
}
int main(){
while(scanf("%d",&n)!=EOF) solve();
return 0;
}
HDU6504 Problem E. Split The Tree【dsu on tree】的更多相关文章
- 【DSU on tree】【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
Description 给定一棵 \(n\) 个节点的树,每条边上有一个字符,字符集大小 \(22\),求每个节点的子树内最长的简单路径使得路径上的字符经过重排后构成回文串. Limitation \ ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
- HDU1325 Is It A Tree? 【并查集】
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
Big binary tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- cdoj32-树上战争(Battle on the tree) 【记忆化搜索】
http://acm.uestc.edu.cn/#/problem/show/32 树上战争(Battle on the tree) Time Limit: 12000/4000MS (Java/Ot ...
- BZOJ2588 Count on a tree 【树上主席树】
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Submit: 7577 Solved: 185 ...
- POJ 3237 Tree 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵树,该树带有边权,现在对该树进行三种操作: 一:改变指定编号边的边权: 二:对树上指定路径的边权全部取反: 三:查询树上指定路径的最大边权值. 解题分析: ...
- LC 431. Encode N-ary Tree to Binary Tree 【lock,hard】
Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the ...
- HDU6430 Problem E. TeaTree【dsu on tree】
Problem E. TeaTree Problem Description Recently, TeaTree acquire new knoledge gcd (Greatest Common D ...
随机推荐
- 浅谈.NET技术公司的实习生培养
浅谈.NET技术公司的实习生培养 背景 近几年.NET开发者市场的越发不景气,一毕业就选择.NET技术的开发者更是少之又少.一方面是公司效益的日益提高,一方面却是招聘优秀人才的速度总是赶不上公司发展的 ...
- 基于 MPI 的快速排序算法的实现
完整代码: #include <iostream> #include <cstdlib> #include <ctime> #include <algorit ...
- PMP知识领域
· 十大知识领域 整合-项目整合管理 识别.定义.组合.统一和协调个项目管理过程组的各种过程和活动而展开的活动与过程. 整合:统一.合并.沟通和简历联系:贯穿项目始终 七个过程组 一.制定项目章程(启 ...
- Centos 打开ssh 密码验证 和 root 登录
# 1 打开系统的密码验证功能: vim /etc/ssh/sshd_config #允许使用密码登录(注释此行 就是允许证书登录) PasswordAuthentication yes # 2 打开 ...
- 【网络】trunk和vlan配置
篇一 : trunk配置和vlan配置 trunk配置 Switch>enable ? ? ?//进入特权模式 Switch#conf t ? ? ?//进入配置模式 Switch(config ...
- thinkpad8平板安装win10系统
ThinkPad8 因为是平板电脑,只有一个micro USB接口,常规安装没法使用鼠标或键盘进行输入,所以难倒很多人. 幸好前段时间买了根otg线和3.0usb hub,安装方法记录如下: 准备:U ...
- 优化太多的if-else
来源java小当家 第1种方法:提前return,减少else判断 1 // 1.优化前 2 private int handlerPre1(boolean flag) { 3 if(flag){ 4 ...
- 1.5V升5V芯片,1.5V升5V电路图规格书
常用的 5号,7号等 1.5V 干电池满电电压在 1.6V 左右,干电池输出耗电电压在 1V.适用PW5100,在 0.9V 时还能输出,彻底榨干干电池的电量. 1.5V 升5V 的芯片:PW5100 ...
- JDK的各个版本
Java的各个版本 从上图我们看出,Java的版本名最开始以JDK开头,后来以j2se开头,最后到现在以Java开头,所以这些名字我们都可以说,但人们说的更多的是JDK多少,或者Java多少
- 本地Mac通过堡垒机代理实现跨堡垒机scp问题
近日,公司在跳板机前架设了堡垒机,以防止ssh攻击,但这带来一个问题,我们平常直接ssh跳板机,可以直接使用scp来上传或下载跳板机数据到本地 架设堡垒之后经常使用的scp工具不好用了 于是本期就来解 ...