lca总结
#include <bits/stdc++.h>
using namespace std;
int n,m,s;
vector <int> e[500001];
int fa[500001],dep[500001],lca[500001][40];
void dfs(int x,int d)
{
dep[x] = d,lca[x][0] = fa[x];
for (int i = 1; i <= 30; i++)
{
lca[x][i] = lca[lca[x][i - 1]][i - 1];
}
for (int i = 0; i < e[x].size(); i++)
{
int v = e[x][i];
if(v != fa[x])
{
fa[v] = x;
dfs(v,d + 1);
}
}
}
int query(int x,int y)
{
if(dep[x] < dep[y])swap(x,y);//x is deeper
for (int i = 30; i >= 0; i--)
{
if(dep[ lca[x][i] ] >= dep[y] && dep[lca[x][i]] > 0)
{
x = lca[x][i];
}
}
if(x == y)return x;
for (int i = 30; i >= 0; i--)
{
if(lca[x][i] == lca[y][i] || lca[x][i] == 0)continue;//overjump
x = lca[x][i],y = lca[y][i];
}
return lca[x][0];
}
int main()
{
scanf(" %d %d %d",&n,&m,&s);
int a,b;
for (int i = 1; i < n; i++)
{
scanf(" %d %d",&a,&b);
e[a].push_back(b),e[b].push_back(a);
}
dfs(s,1);
for (int i = 1; i <= m; i++)
{
scanf(" %d %d",&a,&b);
printf("%d\n",query(a,b));
}
return 0;
}
dfs:处理深度,倍增转移祖先
query:keep x’s depth deeper,从最大的
2
i
2^{i}
2i开始跳,二进制优化,直到跳到同一高度,,再两个一起跳,同上,最后注意,x与y的father才是答案
浙公网安备 33010602011771号