Files
python/TangDou/AcWing/LCA/P3379_Tarjan.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

67 lines
1.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 500010, M = N << 1;
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
vector<PII> query[N]; // query[u]: first:询问的另一个顶点; second:询问的编号
int n, m, s;
int p[N]; // 并查集数组
bool st[N]; // tarjan算法求lca用到的是否完成访问的标识
int lca[N]; // 结果数组
int find(int x) {
if (p[x] != x) p[x] = find(p[x]); // 路径压缩
return p[x];
}
void tarjan(int u) {
// ① 标识u已访问
st[u] = true;
// ② 枚举u的临边,tarjan没有访问过的点
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!st[j]) {
tarjan(j);
// ③ 完成访问后,j点加入u家族
p[j] = u;
}
}
// ④ 每个已完成访问的点,记录结果
for (auto q : query[u]) {
int v = q.first, id = q.second;
if (st[v]) lca[id] = find(v);
}
}
int main() {
memset(h, -1, sizeof h);
scanf("%d %d %d", &n, &m, &s);
int a, b;
for (int i = 1; i < n; i++) {
scanf("%d %d", &a, &b);
add(a, b), add(b, a);
}
for (int i = 1; i <= m; i++) {
scanf("%d %d", &a, &b);
query[a].push_back({b, i});
query[b].push_back({a, i});
}
// 初始化并查集
for (int i = 1; i <= n; i++) p[i] = i;
tarjan(s);
// 输出答案
for (int i = 1; i <= m; i++) printf("%d\n", lca[i]);
return 0;
}