cf 686 D



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

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

#include 
using namespace std;
const int N=3e5+5;

vectorG[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;id[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;
}

        

你可能感兴趣的:(cf,搜索)