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 ...
随机推荐
- mysql的逻辑备份和恢复
备份指定的数据库或此数据库中的某些表 mysqldump [options] db_name [tables] >backup.sql 备份指定的一个或多个数据库 mysqldump --dat ...
- 在项目中应该使用Boolean还是使用boolean?
起因 在公司看代码时,看到了使用Boolean对象来完成业务逻辑判断的操作.和我的习惯不一致,于是引起了一些反思. boolean和Boolean的差别咱就不说了,我们仅探讨使用boolean与Boo ...
- 安装newman error:package exports for 'c:\nmp\node_modules\newman\node_module 解决办法
一.场景描述: 通过npm安装newman时,一直失败. 尝试了很多安装命令: npm install -g newman npm install -g newman --registry=http: ...
- k8s用kubectl管理应用升级,服务发布与回滚,扩缩容
应用升级 Kubectl set image --help 有案例指定新版本 [root@k8s-master ~]# kubectl set image deployment/nginx nginx ...
- CMOS 摄像头的Skipping 和 Binning 模式
在通常的摄像头中,不同的resolution对应不同的帧率.想要提高帧率就要考虑是否需要缩小视野(FOV).若不希望视野缩小,就需要减少resolution. 常用的减少resolution的两种方式 ...
- memory ordering 内存排序
Memory ordering - Wikipedia https://en.wikipedia.org/wiki/Memory_ordering https://zh.wikipedia.org/w ...
- C++ Primer Plus读书笔记(三)复合类型
这节主要是介绍数组.结构体.类等概念,以及new delete内存管理. 1.数组 首先普及一下C++中字符串的概念,只有在结尾有 \0 的才叫字符串, cout 输出字符串也以空字符为标记进行结束输 ...
- 从零开始学Java (四)输入输出
这块内容对于有基础的人没啥好说的... 1 System.out.print("C"); 2 System.out.println(); 上边和下边等价 1 System.out. ...
- 理解 async/await以及对Generator的优势
async await 是用来解决异步的,async函数是Generator函数的语法糖使用关键字async来表示,在函数内部使用 await 来表示异步async函数返回一个 Promise 对象, ...
- MySQL下载地址与Centos7安装MySQL以及启动问题排查
目录 一.MySQL国内镜像下载 二.国内镜像相关站点 三.Centos7安装MySQL5.7 1. 下载并解压至/usr/local 2. 配置信息 3. 用户及用户组管理(提高安全) 4. 初始化 ...