Codeforces 1006E Military Problem(dp)

题意:

给定一个树, 然后有Q次询问。 询问给出U, K。 求以U为根的子树经过深度优先搜索的第K个儿子,如果一个节点有多个儿子,按照儿子从小到大的顺序,依次访问。
解析:

查询的点可以用1到U的距离再加上k值求得,
那么如果这个点的值大于了U所能达到的最大值,就是-1
所以一边dfs记录1到各个点的距离并且用dp【i]记录这个点孩子的最大值即可

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=2e5+100;
int arr[N];
int pre[N];
vector<int>G[N];
int cnt;
int dp[N];
int  dfs(int x,int last)
{
    arr[x]=cnt++;
    pre[cnt-1]=x;
    for(int i=0;i<G[x].size();i++)
        dp[x]=max(dp[x],dfs(G[x][i],x));
    return dp[x]=max(dp[x],arr[x]);
}

int main()
{
    //freopen("D://rush.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n,q,a,b;
    cin>>n>>q;
    for(int i=2;i<=n;i++)
    {
        cin>>a;
        G[a].pb(i);
    }
    for(int i=1;i<=n;i++)
        sort(G[i].begin(),G[i].end());
    cnt=1;
    dfs(1,1);
    while(q--)
    {
        cin>>a>>b;
        if(arr[a]+b-1>dp[a])
            cout<<-1<<endl;
        else
        {
            int x=arr[a]+b-1;
            cout<<pre[x]<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ffgcc/article/details/81087725