链接:http://codeforces.com/problemset/problem/686/D

      寻找以i为根的子树的重心  当我们要求ans[i]的时候可以发现ans[i]一定会在i节点儿子中数量最多的子树当中,所以层层往上推 直到ans[i]=i || d[i]-d[ans[i]]<d[i]/2;

#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;

vector<int>G[N];
int n,m,f[N],ans[N],d[N];  //d[i] 是记录以i为根节点的子数节点大小 ans[i] 为i的重心结果 f[i] 为i的父亲

void dfs(int u)
{
    int tol=1,ma=0,an=u;
    ans[u]=u;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        dfs(v);
        tol+=d[v];
        if(ma<d[v])
        {
            ma=d[v];
            an=v;
        }
    }
    ans[u]=ans[an];
    d[u]=tol;
    while(ans[u]!=u&&d[u]-d[ans[u]]>d[u]/2)
        ans[u]=f[ans[u]];
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n;i++)
    {
        int u;
        scanf("%d",&u);
        G[u].push_back(i);
        f[i]=u;
    }
    dfs(1);
    while(m--)
    {
        int rt;
        scanf("%d",&rt);
        printf("%d\n",ans[rt]);
    }
    return 0;
}