祖孙询问

题目描述

思路

读入的节点+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;
}
posted @ 2019-09-11 22:47  cabbage-leaf  阅读(179)  评论(0编辑  收藏  举报