本题思路:
本题非常直白地告诉我们是按照dfs顺序来传递指令的那么本题也就被破解了 就是一道dfs序问题
那么dfs序问题该怎么解决呢??
按照题意是求从u开始dfs第k个数是多少.那么就是1为根,从根遍历求的顺序储存,其它的点遍历一定在根遍历的子序列中,所以只要求下从u开始遍历找每一个子节点然后存下子节点的顺序和数量即可。
对于每次询问比对子节点数量即可 有则输出序号 无则输出-1;(详情请见代码)
题目描述
(中文翻译版本)
一支军队拥有n个指挥部。编号为1的节点是最高指挥部,没有上级,其余n-1个指挥部有且仅有一个直接上级。
满足下列任一条件时,指挥部y被认为是x的上级
指挥部y是x的直接上级
指挥部y是x的直接上级的上级
举个例子,下图中3号指挥部的下属为5, 6, 7, 8, 9。
更形式地说,这支军队地指挥部可以看作一棵有n个节点的树,节点u表示指挥部u. u的父亲是指挥部u的直接上级,u的祖先是u的上级。根节点1没有父节点,因此也没有上级。
现在,你有q个询问。第i个询问以(ui, ki)的形式给出,ui表示第i个指令是由ui指挥部发出的,ki表示查询第ki个接受到指令的指挥部。
ui的下属接受指令的顺序和对以ui为根的子树进行dfs的顺序是一样的。假设当前位于节点a,首先找到a编号最小的子节点b,向b传达指令。然后对b进行同样的操作。直到以b为根的整棵子树都受到命令。然后返回a,再寻找除b外编号最小的子节点。不断重复这个过程
看向下面这个例子:
如果1号指挥部传达命令,则其他指挥部接受命令的顺序是[1, 2, 3, 5 ,6, 8, 7, 9, 4].
如果3号指挥部传达命令,则其他指挥部接受命令的顺序是[3, 5, 6, 8, 7, 9].
如果7号指挥部传达命令,则其他指挥部接受命令的顺序是[7, 9].
如果9号指挥部传达命令,则其他指挥部接受命令的顺序是[9].
对于第i个问题(ui, ki)。你需要求出从ui出发命令传达到的第ki个指挥部的编号。如果没有这样的指挥部,则输出-1。
请单独处理每个询问,两个询问之间不会相互影响。
Input
第一行包含两个整数n,q(2≤n≤2105,1≤q≤2105),表示指挥部个数和询问个数
第二行包含n-1个整数p2, p3, …, pn (1 ≤ pi < i), pi表示第i个指挥部的直接上级。
接下来q行描述询问。第i个询问包含一个数对(ui, ki) (1 ≤ ui, ki ≤ n),ui是发出命令的指挥部编号,ki表示询问第ki个收到命令的指挥部
Output
共q行,每行一个整数。第i行输出的整数表示从ui发出命令时第ki个收到命令的指挥部编号。如果收到指令的指挥部数量不足ki,则输出 “-1” 。
样例
Input
9 6
1 1 1 3 5 3 5 7
3 1
1 5
3 4
7 3
1 8
1 9
Output
3
6
8
-1
9
4
C++ 代码
#include<iostream>
#include<vector>
using namespace std;
const int N=2e5+10;
int a[N],num[N],b[N];
vector<int>v[N];
int cnt;
void dfs(int u)//
{
a[u]=++cnt;
num[cnt]=u;
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(!a[x]) dfs(x);
}
b[u]=cnt;//记录能收到指令的指挥部数量 即子节点数量
}
int main()
{
int n,q;
cin>>n>>q;
//存储图
for(int i=2;i<=n;i++)
{
int u;
cin>>u;
v[u].push_back(i);//有向图建一边即可
}
dfs(1);//遍历
while(q--)
{
int u,k;
cin>>u>>k;//第u个指挥部发出的命令 问第k个收到命令的指挥部
if(b[u]<a[u]+k-1)//数量不足
{
cout<<-1<<endl;
continue;//别忘了 忘了就裂了
}
cout<<num[a[u]+k-1]<<endl;
}
}