1.两个点的lca
寻找两个点的lca
记录根节点到u的深度为depth[u],到节点v的深度为depth[v]
先让他们的深度保持一致,然后再一起向上走,知道找到lca
*/
vector<int>G[max_n];
int root;
int parent[max_n];
int depth[max_n];
void dfs(int v,int p,int d)
{
parent[v]=p;
depth[v]=d;
for(int i=0;i<G[v].size();i++)
{
if(G[v][i]!=p)dfs(G[v][i],v,d+1);
}
}
void init()
{
dfs(root,-1,0)
}
int lca(int u,int v)
{
while(depth[v]>depth[u]) v=parent[v];
while(depth[u]>depth[v]) u=parent[u];
while(u!=v)
{
u=parent[u];
v=parent[v];
}
return u;
}
2.预处理数组解决多对节点lca问题
/*
parent[k][v]表示v点向根节点走2^k步所到达的点
根据parent数组可以高效地处理多对节点的lca
*/
vector<int>G[max_n];
int parent[200][max_n];
int depth[max_n];
void dfs(int v,int p,int d)
{
parent[0][v]=p;
depth[v]=d;
for(int i=0;i<G[v].size();i++)
{
if(G[v][i]!=v)dfs(G[v][i],v,d+1);
}
}
void init(int v)
{
dfs(root,-1,0);
for(int k=1;k+1<max_n;k++)
{
for(int v=0;v<V;v++)
{
if(parent[k][v]<0) parent[k+1][v]=-1;
else parent[k+1][v]=parent[k][parent[k][v]];
}
}
}
int lca(int u,int v)
{
if(depth[u]>depth[v])swap(u,v);
for(int k=0;k<max_n;k++)
{
if(((depth[v]-depth[u])>>k)&1)
{
u=parent[u];
v=parent[v];
}
}
for(int k=max_n;k>=0;k--)
{
if(parent[k][u]!=parent[k][v])
{
u=parent[k][u];
v=parent[k][v];
}
}
return parent[0][u];
}