题目描述
如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。
#include
#define maxn 500001
struct edge
{
int to, next;
}e[maxn * 2];
int ls[maxn * 2], dep[maxn], f[maxn][21];
bool v[maxn];
int dfs(int now, int de, int fa)
{
f[now][0] = fa;
dep[now] = de;
v[now] = 1;
for (int i = ls[now]; i; i = e[i].next)
{
if (v[e[i].to] == 0)
dfs(e[i].to, de + 1, now);
}
}
int LCA(int l, int r)
{
if (dep[l] < dep[r])
{l ^= r; r ^= l; l ^= r;}
for (int i = 20; i >= 0; i--)
if (dep[r] <= dep[f[l][i]])
l = f[l][i];
if (l == r) return l;
for (int i = 20; i >= 0; i--)
if (f[l][i] != f[r][i])
{
l = f[l][i];
r = f[r][i];
}
return f[l][0];
}
int main()
{
int n, m, root;
scanf("%d%d%d", &n, &m, &root);
v[root] = 1;
int l = 0;
for (int i = 1; i < n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
e[++l] = (edge) {y, ls[x]};
ls[x] = l;
e[++l] = (edge) {x, ls[y]};
ls[y] = l;
}
dfs(root, 1, 0);
for (int j = 1; j <= 20; j++)
for (int i = 1; i <= n; i++)
f[i][j] = f[f[i][j - 1]][j - 1];
for (int i = 1; i <= m; i++)
{
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", LCA(l, r));
}
}
]]>
Comments NOTHING