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;
}