LCA(倍增,Tarjan)

倍增

#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

留坑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值