1. 程式人生 > 實用技巧 >最近公共祖先lca

最近公共祖先lca

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
	int f=1,x=0;
	char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-') f*=-1;
		c=getchar();
	}
	while(isdigit(c))
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

const int N=5e5+9;
int a[N],nxt[N<<1],to[N<<1],head[N],dep[N],fa[N][22],n,m,s,cnt;
void add(int x,int y)
{
	cnt++;
	to[cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
}

void dfs(int x,int father)
{
	fa[x][0]=father;
	dep[x]=dep[father]+1;
	for(int i=1;i<=20;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])
		if(to[i]!=father) dfs(to[i],x);
}

int lca(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=20;i>=0;i--)
		if((1<<i)<=dep[x]-dep[y]) x=fa[x][i];
	if(x==y) return x;
	for(int i=20;i>=0;i--)
		if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}

int main()
{
	n=read(),m=read(),s=read();
	int x,y;
	for(int i=1;i<n;i++)
	{
		x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	dfs(s,0);
	while(m--)
	{
		x=read(),y=read();
		printf("%d\n",lca(x,y));
	}
	return 0;
}