祖孙询问
题目描述
思路
读入的节点+1,代表树上的节点,这样0节点可以成为根节点的父节点,方便dfs
代码
#include <cstdio>
const int MAX = 4e4 + 5;
int n, m, root;
int head[MAX], ver[MAX << 2], nt[MAX << 2], ht;
int f[MAX][17], dep[MAX];
void add(int x, int y) {
nt[++ht] = head[x], head[x] = ht, ver[ht] = y;
}
inline int read() {
int s = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return f * s;
}
void dfs_lca(int x, int y) {
dep[x] = dep[y] + 1;
f[x][0] = y;
for (int i = 1; i < 17; ++i) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i = head[x], j; i; i = nt[i]) {
j = ver[i];
if (j == y) continue;
dfs_lca(j, x);
}
}
bool lca(int x, int y) {
for (int i = 16; i >= 0; --i) {
if (dep[f[x][i]] >= dep[y]) x = f[x][i];
}
return x == y;
}
int main() {
n = read();
for (int i = 1, a, b; i <= n; ++i) {
a = read() + 1, b = read() + 1;
if (b == 0) root = a;
else add(a, b), add(b, a);
// printf("%d %d\n", a, b);
}
dfs_lca(root, 0);
m = read();
for (int i = 1, x, y; i <= m; ++i) {
x = read() + 1, y = read() + 1;
if (x == root) {
putchar('1');
} else if (y == root) {
putchar('2');
} else {
if (dep[x] < dep[y]) {
if (lca(y, x)) putchar('1');
else putchar('0');
} else {
if (lca(x, y)) putchar('2');
else putchar('0');
}
}
puts("");
}
return 0;
}