#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
const int inf = 0x3f;
struct node
{
int v;
int id;
node(int a,int b)
{
v = a;
id = b;
}
};
int n,m,root;
vector<int> g[N];
vector<node> query[N];
int f[N];
int vis[N],ans[N];
int find(int u)
{
if(u == f[u])
{
return u;
}
else
{
return f[u] = find(f[u]);
}
}
void un(int u,int v)
{
f[find(u)] = find(v);
}
void dfs(int u, int f)
{
int i;
for(auto v: g[u])//遍历子结点
{
if(v == f)
{
continue;
}
dfs(v,u);
un(v,u);//以右为王,u为父亲在右边 合并
}
vis[u] = 1;//先标记本身 如果是lca(6,6)则不会存入答案
for(auto temp: query[u])
{
int v = temp.v;//查询对象
int id = temp.id;//离线查询编号
if(vis[v] == 1)//如果已访问
{
ans[id] = find(v);//v当前的父亲,就是u,v的lca
}
}
}
void tar()
{
dfs(root,-1);//跑一遍dfs,找lca
int i;
for(i = 1; i<=m; i++)
{
cout << ans[i] << endl;
}
}
int main()
{
cin >> n >> m >> root;//n个节点 m次查询 root为根节点
int i;
for(i = 1; i<=n-1; i++)//共n-1条边
{
int u,v;
cin >> u >> v;
g[u].push_back(v);//无相图
g[v].push_back(u);
}
for(i = 1; i<=n; i++)//并查集初始化
{
f[i] = i;
}
for(i = 1; i<=m; i++)//离线询问信息
{
int u,v;
cin >> u >> v;
query[u].push_back(node(v,i));//存入查询对象与询问编号
query[v].push_back(node(u,i));
}
tar();
return 0;
}
P3379 【模板】最近公共祖先(LCA)
最新推荐文章于 2022-08-06 18:58:27 发布