AcWing 1172:祖孙询问 ← DFS序
【题目来源】
【题目描述】
给定一棵包含 n 个节点的有根无向树,节点编号互不相同,但不一定是 1∼n。
有 m 个询问,每个询问给出了一对节点的编号 x 和 y,询问 x 与 y 的祖孙关系。
【输入格式】
输入第一行包括一个整数 n 表示节点个数;
接下来 n 行每行一对整数 a 和 b,表示 a 和 b 之间有一条无向边。如果 b 是 −1,那么 a 就是树的根;
第 n+2 行是一个整数 m 表示询问个数;
接下来 m 行,每行两个不同的正整数 x 和 y,表示一个询问。
【输出格式】
对于每一个询问,若 x 是 y 的祖先则输出 1,若 y 是 x 的祖先则输出 2,否则输出 0。
【输入样例】
10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19
【输出样例】
1
0
0
0
2
【数据范围】
1≤n,m≤4×10^4,
1≤每个节点的编号≤4×10^4
【算法分析】
● 假设以某结点 u 为根的子树(含 u 本身)大小为 sz[u],u 在整棵树中的 DFS 序为 ts[u],则可得结点 u 的所有子树对应的 DFS 序区间为 [ts[u],ts[u]+sz[u]-1]。
进而,可得 x 是 y 的祖先的判定代码如下所示:
● 一棵子树的 DFS 序是整棵树的 DFS 序的连续一段。借助 DFS 序,可以快速判断一个结点是否在某个子树内。

例如,上图中以 d 为根的子树,它的 DFS 序 {3,4,5,6} 是整棵树的 DFS 序 {1,2,3,4,5,6,7,8,9} 中的连续一段。
【算法代码】
【参考文献】

浙公网安备 33010602011771号