★实验任务
现有一个树形的消息通信系统,当节点 i 要发送消息时,它会查找它的子节
点,向还没发送过消息的子节点发送消息,如果有多个这样的子节点,则优先选
择节点编号最小的节点,而它的子节点也以同样的策略向下传送消息。当节点 i
的某个子节点完成了消息发送任务后,节点 i 继续查找剩余还没发送过消息的子
节点发送消息,直到节点 i 已经向所有的子节点发送过消息了,则节点 i 完成了
它的消息发送任务。
现有 q 次询问,每次给出一个节点编号 u 和整数 k,问从节点 u 开始发送消
息,则第 k 个收到消息的节点的编号是多少,如果不存在这样的节点,则输出
“-1”。
★数据输入
第一行包含两个整数 n 和 q,表示树中的节点数(2≤n≤2·10^5)和询问的
次数(1≤q≤2·10^5)。
接下来的一行包含 n-1 个整数 pi(1≤i≤n-1) 表示第 i + 1 个节点的父节点
的下标(1≤pi≤i)。节点 1 是根节点。
接下来 q 行,每行两个整数 u 和 k(1≤u, k≤n),u 是开始传播消息的节点
编号,k 表示询问第 k 个收到消息的节点。
★数据输出
输出 q 行,每行表示第 q 次询问的节点编号,如果不存在这样的节点,则
输出“-1”。
输入示例 输出示例
9 6
1 1 1 3 5 3 5 7
3 1
1 5
3 4
7 3
1 8
1 9
输出:
3
6
8
-1
9
4
代码还没还没试过,如果没过再来改如果过了就不改了
这里采用儿子链表表示法来表示这棵树,开一一个数组,数组元素存的内容是节点的父节点,然后又从节点引出一个儿子链表。
遍历方式:递归地遍历,当到达每个节点时,查看有没有儿子链表,有则查看儿子节点,没有则返回(说明此节点是叶节点)。如此递归地遍历树,这题暂时没想出好的做法,只能暴力模拟了≡(▔﹏▔)≡。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#pragma warning(disable:4996)
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
/*
儿子链表表示法表示树
*/
struct Node {//
int number;//数组存的是父亲位置,链表存的是自己的位置
Node* next;
Node(int num):number(num),next(0){}
Node() :number(0), next(0) {}
};
struct Pto {
Node *p;
Pto() :p(0){}
};
Node head[200010];
Pto tail[200010];
void Travel(int sta, int& stp,int aim) {
if (stp == aim) {//到达目标步数
pfd(sta);
return;
}
if (head[sta].next == 0)
return;
else {
Node* p=head[sta].next;
while (p&&stp<aim) {
stp++;//步数加一
Travel(p->number, stp, aim);//访问节点
p = p->next;
}
}
return;
}
int main(void) {
int n, q;
int temp;
Node *ptr=0;
sf2d(n, q);
for (int i = 2; i <= n; i++) {
sfd(temp);
head[i].number = temp;//记录父亲 ///把temp存进i里面
ptr = new Node(i);//i为自己的编号
//把i存进temp里面
if (tail[temp].p == 0) {//才有第一个儿子
head[temp].next = tail[temp].p = ptr;
ptr->next = 0;
}
else {
tail[temp].p->next = ptr;
tail[temp].p = ptr;
ptr->next = 0;
}
}
int sta, stp,aim;
for (int j = 0; j < q; j++) {
sf2d(sta,aim);
stp = 1;
Travel(sta, stp, aim);
if (stp < aim)
pfd(-1);
}
return 0;
}