codeforces 686D. Kay and Snowflake 树的重心应用

D. Kay and Snowflake
time limit per test
3 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 0001 ≤ 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
Note
codeforces 686D. Kay and Snowflake 树的重心应用_第1张图片

The first query asks for a centroid of the whole tree — this is node 3. If we delete node 3 the tree will split in four components, two of size1 and two of size 2.

The subtree of the second node consists of this node only, so the answer is 2.

Node 3 is centroid of its own subtree.

The centroids of the subtree of the node 5 are nodes 5 and 6 — both answers are considered correct.


题意:给一颗有向边的树,根节点为 1,q次询问,询问以该点为根节点的子树的重心编号。


树的重心定义(另一种):以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。


树的重心的性质:

性质 1 :树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离

和,他们的距离和一样。


性质 2 :把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵

树重心的路径上。


性质 3 :一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。


      这道题如果询问次数少的话可以直接利用树的重心模版来做,不过看成双向边,不

往指的根节点上面走就是了。但是这个询问30W,模版来就是n方的复杂度肯定不行

了。

      这时就可以利用树的重心的第二个性质,对于我们从点1开始往下进行遍历,返回

的时候就可以可以看成一颗树与另一颗树相连求重心。然后就是这个性质2了。由于这

颗树的特殊性,有子树的坐标,一只沿着父亲跑到当前结点找到重心就行了。


CODE

#include 
using namespace std;
const int N = 300000+10;
int n,q;
vector G[N]; ///存图
int ans[N];       ///答案
int son[N];       ///包括自身在内有多少子树结点
int fa[N];        ///输入用,同时代表这个点的父亲

void dfs(int u){
    ans[u] = u;
    son[u] = 1;
    for(int i = 0;i < G[u].size();i++){
        int v = G[u][i];
        dfs(v);
        son[u] += son[v];
    }
    for(int i = 0;i < G[u].size();i++)      ///重心存在于子树中,记录子树重心的位置
        if(son[G[u][i]]*2 > son[u])         ///*2是利用重心的性质
            ans[u] = ans[G[u][i]];
    while((son[u]-son[ans[u]])*2 > son[u])  ///重新连接后的重心一定在子树重心和当前结点的路径上
        ans[u] = fa[ans[u]];
}

int main(void)
{
    scanf("%d%d",&n,&q);
    for(int i = 2;i <= n;i++){
        scanf("%d",&fa[i]);
        G[fa[i]].push_back(i);
    }
    dfs(1);
    for(int i = 1;i <= q;i++){
        int qq;
        scanf("%d",&qq);
        printf("%d\n",ans[qq]);
    }
    return 0;
}






你可能感兴趣的:(树的重心)