You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 40010, M = 80010;
//链式前向星
int e[M], h[N], idx, ne[M];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int n;
int depth[N];
int f[N][16];
//树上深搜
void dfs(int u) {
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!depth[j]) {
depth[j] = depth[u] + 1; //① 每个节点的深度
f[j][0] = u; //② j的父节点是u
dfs(j);
}
}
}
int lca(int a, int b) {
if (depth[a] < depth[b]) swap(a, b);
for (int k = 15; k >= 0; k--)
if (depth[f[a][k]] >= depth[b]) a = f[a][k];
if (a == b) return a;
return f[a][0];
}
int main() {
memset(h, -1, sizeof h); //初始化链式前向星
scanf("%d", &n); // n个顶点
int a, b, m, root;
while (n--) {
scanf("%d %d", &a, &b); //表示a和b之间有一条无向边。如果b是1那么a就是树的根
if (b == -1)
root = a;
else
add(a, b), add(b, a); //有根无向树
}
//从根开始进行处理根的深度是1
depth[root] = 1;
dfs(root); //从根开始深搜,目标是 ①:给每个节点标识上深度 ②:给每个节点设置上打表f[i][0]的值,其实就是他爹是谁
// dfs只解决了2^0问题其它的2^1,2^2,2^3,...,2^k,还需要再写循环自己实现这个顺序与bfs不一样bfs根据深度枚举遇到i时它的依赖前序都已准备好 dfs需要全跑完再来一遍
// 这个枚举序挺烦人啊dp枚举顺序是配合业务来的,从这个来看固定好2^i然后逐个枚举每个点号进行填充
// 所以yxc大佬没有讲按dfs进行标识深度而是采用了bfs进行标识bfs是很好理解
for (int i = 1; i <= 15; i++)
for (int j = 1; j <= N; j++)
f[j][i] = f[f[j][i - 1]][i - 1];
scanf("%d", &m);
while (m--) {
scanf("%d %d", &a, &b);
int p = lca(a, b);
if (p == a)
puts("1");
else if (p == b)
puts("2");
else
puts("0");
}
return 0;
}