lca(倍增)

、#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1000000+10;
int fa[maxn>>1][20],e,to[maxn],be[maxn],ne[maxn],deep[maxn];
bool p[maxn];
void add(int x,int y){
	to[++e] = y;
	ne[e] = be[x];
	be[x] = e;
}
void dfs(int x){
	p[x] = 1;
	for(int i = be[x];i;i = ne[i]){
		int v = to[i];
		if( !p[v] ){
			fa[v][0]=x;
			deep[v]=deep[x]+1;
			dfs(v);	
		}
	}
}
void build(int n){
	int k = log(n)/log(2);
	for(int i = 1;i <= k; i++ ){
		for(int j = 1;j <= n; j++ ){
			if(fa[j][i-1]!=0&&fa[fa[j][i-1]][i-1]!=0)
				fa[j][i] = fa[fa[j][i-1]][i-1];
		}
	}
}
int query(int x,int y){
	if(deep[x]<deep[y])swap(x,y);
	int t;
	for(t = 0; (1<<t)<=deep[x];t++);
	t--;
	for(int i = t;i >= 0;i--){
		if(deep[x]-(1<<i)>=deep[y]){
			x = fa[x][i];
		}
	}
	if(x==y)return x;
	for(int i = t;i>=0;i--){
		if(fa[x][i]!=0&&fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
		}			
	}
	return fa[x][0];
} 
int main(){
	int i,j,k,m,n;
	scanf("%d%d%d",&n,&m,&k);
	for(i = 0; i<n-1 ;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	deep[k]=1;
	dfs(k);
	build(n);
	while(m--){
		int u,v;
		scanf("%d%d",&u,&v);
		printf("%d\n",query(u,v));
	}
	return 0;
}

posted @ 2017-01-13 11:55  Drinkwater_cnyali  阅读(122)  评论(0编辑  收藏  举报