#lCAybttg040406. 1557:祖孙询问
1557:祖孙询问
题目描述
已知一棵 个节点的有根树。有 个询问,每个询问给出了一对节点的编号 和 ,询问 与 的祖孙关系。
输入格式
输入第一行包括一个整数 表示节点个数;
接下来 行每行一对整数对 和 表示 和 之间有连边。如果 是 ,那么 就是树的根;
第 行是一个整数 表示询问个数;
接下来 行,每行两个正整数 和 ,表示一个询问。
输出格式
对于每一个询问,输出一行一个整数:
- 若 是 的祖先则输出 ;
- 若 是 的祖先则输出 ;
- 否则输出 。
样例
输入样例 1
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
1
0
0
0
2
样例解释
树的结构(括号内为节点编号):
234 (根)
/ / | | | | \ \ \
12 13 14 15 16 17 18 19
\
233
- 询问 : 是 的祖先 → 输出 。
- 询问 : 不是 的祖先, 也不是 的祖先 → 输出 。
- 询问 :同理 → 输出 。
- 询问 :同理 → 输出 。
- 询问 : 是 的祖先 → 输出 。
数据范围
- 每个节点的编号不超过
时间限制:1000 ms
内存限制:524288 KB
提示
判断祖孙关系等价于判断一个节点是否在另一个节点的子树中。
在有根树中,我们可以通过 DFS 序来判断:对树进行一次 DFS,记录每个节点进入的时间戳 和离开的时间戳 。那么节点 是节点 的祖先当且仅当:
$$in[u] \le in[v] \quad \text{且} \quad out[v] \le out[u]$$因为 的子树中所有节点的 DFS 序都在 区间内。
实现步骤:
- 读入边,确定根节点。
- 从根开始 DFS,记录 和 ,同时可以记录深度 (可选)。
- 对于每个询问 :
- 如果 且 ,输出 ;
- 否则如果 且 ,输出 ;
- 否则输出 。
时间复杂度:DFS ,每个询问 ,总复杂度 ,完全可以通过。
注意:节点编号范围较大且不连续,可以用数组直接存储(因为不超过 ),或者用 map 映射,但推荐直接用数组,输入时记录最大编号即可。