P3379 【模板】最近公共祖先(LCA)

链接Miku

树刨理论

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=500001;
int n,m,s;
int fa[maxn];
int son[maxn];
int siz[maxn];
int dee[maxn];
int top[maxn];
int head[maxn];
int p;
int x,y;
struct e{
	int to;
	int f;
	int ne;
}ed[maxn*2+1];
void add(int f,int t){
	p++;
	ed[p].f=f;
	ed[p].to=t;
	ed[p].ne=head[f];
	head[f]=p;
	return ;
}
void dfs1(int now,int f){
	siz[now]=1;
	fa[now]=f;
	dee[now]=dee[f]+1;
	for(int i=head[now];i;i=ed[i].ne){
		if(ed[i].to==f)
		continue;
		dfs1(ed[i].to,now);
		siz[now]+=siz[ed[i].to];
		if(!son[now]||siz[son[now]]<siz[ed[i].to]){
			son[now]=ed[i].to;
		}
	}
	return ;
}
void dfs2(int now,int f){
	top[now]=f;
	for(int i=head[now];i;i=ed[i].ne){
		if(ed[i].to==fa[now]) continue;
		else if(ed[i].to==son[now]) dfs2(ed[i].to,f);
		else dfs2(ed[i].to,ed[i].to);
	} 
	return ;
}
int main(){
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<n;++i){
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs1(s,s); 
	dfs2(s,s);
	for(int i=1;i<=m;++i){
		scanf("%d%d",&x,&y);
		while(top[x]!=top[y]){
			dee[top[x]]>=dee[top[y]] ? x=fa[top[x]] :y=fa[top[y]];
		}
		x= dee[x]>dee[y] ? y:x;
		cout<<x<<endl;
	}
	return 0;
}
posted @ 2020-09-05 20:03  Simex  阅读(107)  评论(0编辑  收藏  举报