用C++
时间: 2023-07-11 20:13:31 浏览: 92
以下是使用 C++ 实现的代码:
```c++
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 50000
#define MAXM 500000
#define MAXLOGN 16
int n, m;
int fa[MAXN][MAXLOGN], dep[MAXN];
int head[MAXN], to[MAXM << 1], nxt[MAXM << 1], tot;
void add_edge(int u, int v) {
to[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
}
void dfs(int u, int f, int d) {
fa[u][0] = f;
dep[u] = d;
for (int i = 1; i < MAXLOGN; i++) {
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for (int i = head[u]; i; i = nxt[i]) {
int v = to[i];
if (v != f) {
dfs(v, u, d + 1);
}
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) {
int tmp = u;
u = v;
v = tmp;
}
for (int i = MAXLOGN - 1; i >= 0; i--) {
if (dep[fa[u][i]] >= dep[v]) {
u = fa[u][i];
}
}
if (u == v) {
return u;
}
for (int i = MAXLOGN - 1; i >= 0; i--) {
if (fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][0];
}
int main() {
while (scanf("%d", &n) && n) {
memset(head, 0, sizeof(head));
tot = 0;
for (int i = 1; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
dfs(0, 0, 0);
scanf("%d", &m);
while (m--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int ab = lca(a, b);
int ac = lca(a, c);
int bc = lca(b, c);
if ((ab == ac && lca(c, b) == b) || (ab == bc && lca(c, a) == a)) {
printf("Yes\n");
} else {
printf("No\n");
}
}
}
return 0;
}
```
同样地,上面的代码假设输入的节点编号从 $0$ 到 $n-1$,如果从 $1$ 到 $n$,需要将输入的节点编号减一。
阅读全文