#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cout<<"["<<"x = "<<(x)<<"] "
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e6 + 5;
const int mod = 998244353;
/*
tarjan离线求LCA
*/
struct node {
int v, nxt;
} e[maxn];
int tot, head[maxn];
void add_edge(int u, int v) {//存边
e[tot].v = v;
e[tot].nxt = head[u];
head[u] = tot++;
e[tot].v = u;
e[tot].nxt = head[v];
head[v] = tot++;
}
struct qnode {//存查询
int id, v, nxt;
} qe[maxn];
int qtot, qhead[maxn];
void add_q(int u, int v, int id) {//双向的
qe[qtot].v = v;
qe[qtot].id = id;
qe[qtot].nxt = qhead[u];
qhead[u] = qtot++;
qe[qtot].v = u;
qe[qtot].id = id;
qe[qtot].nxt = qhead[v];
qhead[v] = qtot++;
}
int f[maxn];
int getf(int x) {//并查集
return f[x] == x ? x : f[x] = getf(f[x]);
}
int n, m, s, ans[maxn], vis[maxn];//ans存答案
void init() {//初始化
CLR(head, -1);
CLR(qhead, -1);
CLR(vis, 0);
tot = qtot = 0;
for(int i = 1; i <= n; i++) f[i] = i;
}
void dfs(int u) {//递归查询答案
vis[u] = 1;
for(int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
if(!vis[v]) {
dfs(v);
int t1 = getf(u);
int t2 = getf(v);
if(t1 != t2) {//合并
f[t2] = t1;
}
}
}
for(int i = qhead[u]; ~i; i = qe[i].nxt) {
int v = qe[i].v;
if(vis[v]) {//如果当前查询的另一个节点已经被访问过,就能确定答案了
ans[qe[i].id] = getf(v);
}
}
}
int main() {
scanf("%d%d%d", &n, &m, &s);
init();
for(int i = 1; i <= n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v);
}
for(int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
add_q(u, v, i);
}
dfs(s);
for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
return 0;
}
离线tarjan算法求LCA
猜你喜欢
转载自blog.csdn.net/yiqzq/article/details/81591271
今日推荐
周排行