LCA实现方法
1.dfs搜索树形成欧拉序列用st算法维护区间最值
2.tarjan离线求lca
3.树上倍增实现lca(方法如下)
模板代码
#include<bits/stdc++.h>
#define maxn 100
#define max2 20
using namespace std;
struct<span style="white-space:pre"> </span>node
{
int to,next;
} poi[maxn*2];
int head[maxn],fa[maxn][max2],f[maxn],d[maxn];
int cnt;
int init_build(int n)
{
cnt=0;
for (int i=1; i<=n; i++)
head[i]=0;
}
int ins(int u,int v)
{
poi[++cnt].to=v;
poi[cnt].next=head[u];
head[u]=cnt;
}
int init_dfs(int n)
{
memset(f,1,sizeof(f));
int m=int (log(n*1.0)/log(2.0));
for (int i=0; i<=m; i++)
fa[1][i]=1;
}
int dfs(int u,int depth)
{
f[u]=0;
d[u]=depth;
int p=head[u];
while (p!=0)
{
if (f[poi[p].to])
{
fa[poi[p].to][0]=u;
f[poi[p].to]=0;
dfs(poi[p].to,depth+1);
}
p=poi[p].next;
}
return 0;
}
int redouble_dp(int n)
{
int m=int (log(n*1.0)/log(2.0));
for (int j=1; j<=m; j++)
for (int i=2; i<=n; i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
return 0;
}
int lca(int x,int y,int n)
{
if (d[x]<d[y]) swap(x,y);
int m=int (log(n*1.0)/log(2.0));
if (d[x]!=d[y])
{
for (int j=m; j>=0; j--)
{
if (d[x]-((1<<j))<0)
continue;
if (d[fa[x][j]]>=d[y])
x=fa[x][j];
if (d[x]==d[y])
break;
}
for (int j=m; j>=0; j--)
{
if (x==y)
break;
if (d[x]-((1<<j))<0)
continue;
if (fa[x][j]!=fa[y][j])
{
x=fa[x][j];
y=fa[y][j];
}
}
if ((fa[x][0]!=fa[y][0])&&(x!=y))
return 0;
if (x==y)
return x;
else return fa[x][0];
}
}
int main()
{
int n;
cin>>n;
init_build(n);
for (int i=0; i<n-1; i++)
{
int x,y;
cin>>x>>y;
ins(x,y);
ins(y,x);
}
init_dfs(n);
dfs(1,0);
redouble_dp(n);
int m;
cin>>m;
for (int i=0; i<m; i++)
{
int x,y;
cin>>x>>y;
cout<<x<<"->"<<y<<":"<<lca(x,y,n)<<endl;
}
return 0;
}