模板: 树链剖分求LCA

void dfs1(int x)
{
	size[x]=1;
	for(int i=head[x];i;i=e[i].next)
	{
		int y=e[i].to; 
		if(dep[y]) continue;
		dep[y]=dep[x]+1; fa[y]=x;
		dfs1(y); 
		size[x]+=size[y];
		if(size[son[x]]<size[y]) son[x]=y;
	}
}

void dfs2(int x,int tp)
{
	top[x]=tp; 
	if(son[x]) dfs2(son[x],tp);
	for(int i=head[x];i;i=e[i].next)
	{
		int y=e[i].to;
		if(y==son[x]||y==fa[x]) continue;
		dfs2(y,y);	
	}
}

int LCA(int x,int y)
{
	while(top[x]!=top[y])
		dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];//topx与topy 
	return dep[x]<dep[y]?x:y;
}

int main()
{
	n=read(); m=read(); s=read();
	for(int i=1;i<n;i++) add(read(),read());
	dep[s]=1; fa[s]=0;
	dfs1(s); dfs2(s,s);
	while(m--)
		printf("%d\n",LCA(read(),read()) );
	return 0;
}

注意: 树链剖分比较的是\(dep[top[x]]\ \& \ dep[top[y]]\)

posted @ 2022-01-16 20:03  __iostream  阅读(21)  评论(0)    收藏  举报