Codeforces Round #359 (Div. 2) D. Kay and Snowflake
2016-07-01 14:18
337 查看
D. Kay and Snowflake
time limit per test3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
After the piece of a devilish mirror hit the Kay’s eye, he is no longer interested in the beauty of the roses. Now he likes to watch snowflakes.
Once upon a time, he found a huge snowflake that has a form of the tree (connected acyclic graph) consisting of n nodes. The root of tree has index 1. Kay is very interested in the structure of this tree.
After doing some research he formed q queries he is interested in. The i-th query asks to find a centroid of the subtree of the node vi. Your goal is to answer all queries.
Subtree of a node is a part of tree consisting of this node and all it’s descendants (direct or not). In other words, subtree of node v is formed by nodes u, such that node v is present on the path from u to root.
Centroid of a tree (or a subtree) is a node, such that if we erase it from the tree, the maximum size of the connected component will be at least two times smaller than the size of the initial tree (or a subtree).
Input
The first line of the input contains two integers n and q (2 ≤ n ≤ 300 000, 1 ≤ q ≤ 300 000) — the size of the initial tree and the number of queries respectively.
The second line contains n - 1 integer p2, p3, …, pn (1 ≤ pi ≤ n) — the indices of the parents of the nodes from 2 to n. Node 1 is a root of the tree. It’s guaranteed that pi define a correct tree.
Each of the following q lines contain a single integer vi (1 ≤ vi ≤ n) — the index of the node, that define the subtree, for which we want to find a centroid.
Output
For each query print the index of a centroid of the corresponding subtree. If there are many suitable nodes, print any of them. It’s guaranteed, that each subtree has at least one centroid.
Example
Input
7 4
1 1 3 3 5 3
1
2
3
5
Output
3
2
3
6
题意
定义一棵树的重心为树上的一个节点,如果删除这个节点,分开的几个部分中,最大的节点数小于等于原树的1/2。现在给定一棵树,有q个询问,问树上某点的重心是谁
思路
q数量很大,所以肯定是预处理出每个节点的重心,然后o(1)查询。对于重心应该有这样一个结论:设节点v上最大的子树的重心为u,那么v的重心一定出现在路径uv上。
那么我们可以通过dfs遍历每个节点,当前节点依次判断路径uv上的每个点,找到满足重心要求的即可。
代码
#include <cstdio> #include <vector> #include <algorithm> using namespace std; struct point { int v,f,l,numson,maxson; vector<int>son; }p[300010]; int dfs(int n) { p .l=p .son.size(); if (p .l) { int be,a,b=0; for (int i=0;i<p .l;i++) { a=dfs(p .son[i]); p .numson+=a; if (p .maxson<a) { be=p[p .son[i]].v; p .maxson=a; } } p .numson++; do { int ok=1; if (p[be].maxson*2>p .numson) ok=0; if (p[be].numson*2<p .numson) ok=0; if (ok) { p .v=be; break; } be=p[be].f; }while (be!=p .f); } else { p .v=n; p .numson++; } return p .numson; } int main() { int n,q,x; scanf("%d %d",&n,&q); for (int i=2;i<=n;i++) { scanf("%d",&x); p[x].son.push_back(i); p[i].f=x; } dfs(1); for (int i=1;i<=q;i++) { scanf("%d",&x); printf("%d\n",p[x].v); } }
相关文章推荐
- CSS实现隐藏和显示功能的代码
- icinga 监控中文版 安装部署
- 使用Autolayout xib实现动态高度的TableViewCell
- search文件中的config
- 周末学习
- 面试题5:从尾到头打印链表
- c++模板特化
- Android系统访问串口设备
- 模拟实现string类
- Spring 4.3 的新功能和增强
- Android图片加载到底哪家强
- Git 少用 Pull 多用 Fetch 和 Merge
- Mac系统终端命令行不执行命令 总出现command not found解决方法
- 传统的ajax将被fetch替代
- js拼接table查询信息部分
- 07.01工作笔记
- redis采用序列化方案存对象
- Associated Objects
- Android中ViewStub控件分析及使用
- mybatis