P3379 【模板】最近公共祖先(LCA)
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 500010
vector<pair<int, int> > que[MAXN];
int vis[MAXN];
int pre[MAXN], head[MAXN];
int ans[MAXN];
int cnt, n, q, s;
struct Edge{
int to;
int next;
}edge[MAXN<<1];
void Init(){
cnt = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++){
que[i].clear();
pre[i] = i;
}
}
void add(int x, int y){
edge[++cnt].next = head[x];
edge[cnt].to = y;
head[x] = cnt;
}
inline int find(int x){
int r = x;
while (pre[r] != r) r = pre[r];
int i = x, j;
while (i != r){
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
inline void join(int x, int y){
int fx = find(x), fy = find(y);
if (fx != fy) pre[fx] = fy;
}
void Tarjan(int x){
vis[x] = 1;
for (int i = head[x]; i != -1; i = edge[i].next){
int to = edge[i].to;
if (!vis[to]){
Tarjan(to);
join(to, x);
}
}
for (int i = 0; i < que[x].size(); i++){
if (vis[que[x][i].first])
ans[que[x][i].second] = find(que[x][i].first);
}
}
int main() {
scanf("%d%d%d", &n, &q, &s);
Init();
int x, y;
for (int i = 1; i < n; i++){
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
for (int i = 0; i < q; i++){
scanf("%d%d", &x, &y);
que[x].push_back(make_pair(y, i));
que[y].push_back(make_pair(x, i));
}
Tarjan(s);
for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
return 0;
}