我发现我在另一个oj上做过,直接发手题解
lca模板
利用dfs找到每个点的父亲和每个点的深度
利用一个循环初始化一个点上面第(1<<i)个父亲是什么
对于每个询问在线跑一遍 倍增求lca
不理解倍增思路看这里
设两点 a,b(a的深度大于b)
首先让a倍增跳到于b同深度
如果此时a,b相等,返回
如果不相等,那么同时向上跳
一个大佬更详细的讲解
#include<bits/stdc++.h>
using namespace std;
int n,q;
int head[100005];
struct oppo{
int to,next;
}rood[200005];
int tot,start;
void add(int from,int to)
{
rood[++tot].to=to;
rood[tot].next=head[from];
head[from]=tot;
}
int deep[100005];
int fa[100005][25];
void dfs(int x)
{
for(int i=head[x];i;i=rood[i].next)
if(!deep[rood[i].to])
{
deep[rood[i].to]=deep[x]+1;
fa[rood[i].to][0]=x;
dfs(rood[i].to);
}
}
int lca(int x,int y)
{
int fff=1;
if(deep[x]>deep[y])
{
swap(x,y);
fff=2;
}
for(int i=20;i>=0;i--)
if(deep[fa[y][i]]>=deep[x])
y=fa[y][i];
if(x==y)
return fff;
else
return 0;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d %d",&a,&b);
if(b==-1)
start=a;
else
{
add(a,b);
add(b,a);
}
}
deep[start]=1;
dfs(start);
for(int i=1;i<=20;i++)
for(int j=1;j<=40000;j++)
fa[j][i]=fa[fa[j][i-1]][i-1];
cin>>q;
for(int i=1;i<=q;i++)
{
int x,y;
scanf("%d %d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}
yxc赞过!
佬文章收费了😭