社区讨论
求助LCA板子(玄关
灌水区参与者 5已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @lu59sz2c
- 此快照首次捕获于
- 2024/03/24 16:41 2 年前
- 此快照最后确认于
- 2024/03/24 19:09 2 年前
rt,萌新才学LCA,不知道哪里写挂了
CPP#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 2e5 + 10, M = 2 * N;
int n, m;
int rt;
int p[N][35];
int h[N], e[M], ne[M], idx, d[N], fa[N];
inline void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
inline void dfs(int x, int de)
{
d[x] = de;
for (int i = h[x]; i != -1; i = ne[i])
{
int j = e[i];
// if (e[i] == fa[x]) continue;
dfs(j, de + 1);
}
}
inline void init()
{
memset(p, -1, sizeof p);
for (int i = 1; i <= n; i ++ ) p[i][0] = fa[i];
for (int j = 1; (1 << j) <= n; j ++ )
for (int i = 1; i <= n; i ++ )
if (p[i][j - 1] != -1)
p[i][j] = p[p[i][j - 1]][j - 1];
}
inline int lca(int a, int b)
{
int k = (int)(log2(d[a]));
for (int i = k; i >= 0; i -- )
if (d[a] - (1 << i) >= d[b])
a = p[a][i];
if (a == b) return a;
for (int i = k; i >= 0; i -- )
if (p[a][i - 1] != -1 && p[a][i] != p[b][i]) a = p[a][i], b = p[b][i];
return p[a][0];
}
int main()
{
// memset(fa, -1, sizeof fa);
memset(h, -1, sizeof h);
scanf("%d%d", &n, &m);
int nc = n - 1, x, y;
while (nc -- )
{
scanf("%d%d", &x, &y);
add(x, y);
// add(y, x);
fa[y] = x;
}
rt = 1;
while (fa[rt] != 0) rt = fa[rt];
/* for (int i = 1; i <= n; i ++ )
if (fa[i] == 0)
{
rt = i;
break;
}*/
dfs(rt, 1);
// for (int i = 1 ; i <= n; i ++ ) cout << d[i] << '\n';
init();
while (m -- )
{
scanf("%d%d", &x, &y);
if (d[x] < d[y]) swap(x, y);
printf("%d\n", lca(x, y));
}
return 0;
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...