0
点赞
收藏
分享

微信扫一扫

LCA(倍增,Tarjan)

小迁不秃头 2022-01-22 阅读 28
图论

LCA

倍增

#include<bits/stdc++.h>
//#define max(a,b) (((a) > (b)) ? (a) : (b))
using namespace std;
int n,T,root,deep[500010],maxdeep,f[500010][25];
int tot,h[500010],top;
struct node{
	int next,to;
}e[2*500010];
void add(int u,int v)
{
	++tot;
	e[tot].to=v;
	e[tot].next=h[u];
	h[u]=tot;
}
void build(int u)
{
	for(int i=h[u]; i; i=e[i].next)
	{
		int v=e[i].to;
		if(v != f[u][0])
		{
			deep[v]=deep[u]+1;
			f[v][0]=u;
			maxdeep=max(maxdeep,deep[v]);
			build(v);
		}
	}
}
int lca(int u,int v)
{
	if(deep[u] < deep[v]) swap(u,v);
	for(int i=top; i>=0; i--) if(deep[f[u][i]] >= deep[v]) u=f[u][i];
	if(u == v) return v;
	for(int i=top; i>=0; i--)
	{
		if(f[u][i] != f[v][i])
		{
			u=f[u][i];
			v=f[v][i];
		}
	}
	return f[u][0];    //   注意!!
}
int main()
{
	scanf("%d%d%d",&n,&T,&root);
	for(int i=1; i<n; i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	deep[root]=1;
	build(root);
	for( ; (1<<top) <= maxdeep; top++);
	for(int j=1; j<=top; j++)
		for(int i=1; i<=n; i++)
			f[i][j]=f[f[i][j-1]][j-1];
	while (T--)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		printf("%d\n",lca(u,v));
	}
	return 0;
}

tarjan

留坑

举报

相关推荐

0 条评论