树的DFS

树的DFS

给定一棵 n 个节点的树。

节点的编号为 1n,其中 1 号节点为根节点,每个节点的编号都大于其父节点的编号。

现在,你需要回答 q 个询问。

每个询问给定两个整数 ui,ki

我们希望你用 DFS(深度优先搜索)算法来遍历根节点为 ui 的子树。

我们规定,当遍历(或回溯)到某一节点时,下一个遍历的目标应该是它的未经遍历的子节点中编号最小的那一个子节点。

例如,上图实例中:

  • 如果遍历根节点为 1 号节点的子树,则子树内各节点的遍历顺序为 [1,2,3,5,6,8,7,9,4]
  • 如果遍历根节点为 3 号节点的子树,则子树内各节点的遍历顺序为 [3,5,6,8,7,9]
  • 如果遍历根节点为 7 号节点的子树,则子树内各节点的遍历顺序为 [7,9]
  • 如果遍历根节点为 9 号节点的子树,则子树内各节点的遍历顺序为 [9]

每个询问就是让你计算采用规定的 DFS 算法来遍历根节点为 ui 的子树时,第 ki 个被遍历到的节点的编号。

输入格式

第一行包含两个整数 n,q

第二行包含 n1 个整数 p2,p3,,pn,其中 pi 表示第 i 号节点的父节点的编号。

接下来 q 行,每行包含两个整数 ui,ki,表示一组询问。

输出格式

q 行,每组询问输出一行一个整数表示第 ki 个被遍历到的节点的编号。

如果第 ki 个被遍历到的节点不存在,则输出 1

数据范围

前三个测试点满足 2n201q20
所有测试点满足 2n2×1051q2×1051pi<i1ui,kin

输入样例:

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

 

解题思路

  这题还是很简单的,不过因为周赛第一题看错题意,结果卡了40分钟,最后来不及写完这题。

  题目就是问一棵树深度优先遍历的序列。然后给的一个结点编号,求以这个结点为子树的深度优先遍历序列的第k个结点。

  可以发现,每一棵子树在dfs序列中,一定是连续的一段。

  因此,先将整棵树的dfs序列求出来,然后求以u为根节点的子树的dfs序列中的第k个结点,这个序列一定是u后面连续的一段,如果k大于这个子树的大小,则无解。

  AC代码如下:

复制代码
 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 vector<int> graph[N];
 9 int order[N], h[N], cnt;    // order存放dfs序列,h是每个结点在order中的下标映射
10 int sum[N];     // sum存放每个以结点为子树的大小
11 
12 int dfs(int src) {
13     order[cnt] = src;
14     h[src] = cnt++;
15     sum[src] = 1;
16     
17     for (auto &it : graph[src]) {
18         sum[src] += dfs(it);
19     }
20     
21     return sum[src];
22 }
23 
24 int main() {
25     int n, m;
26     scanf("%d %d", &n, &m);
27     for (int i = 2; i <= n; i++) {
28         int root;
29         scanf("%d", &root);
30         graph[root].push_back(i);
31     }
32     
33     dfs(1);
34     
35     while (m--) {
36         int u, k;
37         scanf("%d %d", &u, &k);
38         if (k > sum[u]) printf("-1\n");
39         else printf("%d\n", order[h[u] + k - 1]);
40     }
41     
42     return 0;
43 }
复制代码

 

参考资料

  DFS序列:https://www.acwing.com/video/3723/

posted @   onlyblues  阅读(271)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示