树的遍历——求从第ta节点走aim步到达的节点

★实验任务
现有一个树形的消息通信系统,当节点 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;
}


发布了54 篇原创文章 · 获赞 6 · 访问量 4910

猜你喜欢

转载自blog.csdn.net/jiruqianlong123/article/details/83055726