LCA 大红大紫,闻佬多,遂求条,悬管
  • 板块灌水区
  • 楼主20090818Cc
  • 当前回复15
  • 已保存回复16
  • 发布时间2025/1/22 20:47
  • 上次更新2025/1/23 00:51:21
查看原帖
LCA 大红大紫,闻佬多,遂求条,悬管
1268457
20090818Cc楼主2025/1/22 20:47

小可初学“树连刨分”,见旧人曰LCA,大喜,遂入,已而完,红紫交加,不信,复交几方,皆大败而归,闻luoguo有一宝地,故求调QMQ link

link

#include<bits/stdc++.h>
using namespace std;
const int M=5e5+1;
int read(){
	int sum=0,k=1;char c=getchar();
	while(c<'0'&&c>'9'){
		if(c=='-')k=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		sum=sum*10+c-'0';
		c=getchar();
	}
	return sum*k;
}
struct Node{
	int next,to;
}e[M];
int head[M],k=0;
void adde(int u,int v){
	k++;
	e[k].next=head[u];
	e[k].to=v;
	head[u]=k;
}
int Tree_Size[M];
int Tree_Son[M];
int fa[M];
int Deep[M];
void Build_Dfs(int u,int ft){
	Tree_Size[u]=1;
	Deep[u]=Deep[ft]+1;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==ft) continue;
		fa[v]=u;
		Build_Dfs(v,u);
		Tree_Size[u]+=Tree_Size[v];
		if(Tree_Size[Tree_Son[u]]<Tree_Size[v]){
			Tree_Son[u]=v;
		}
	}
}
int toop[M];
void Find_Root_Dfs(int u,int Top){
	toop[u]=Top;
	if(Tree_Son[u]==0) return ;
	Find_Root_Dfs(Tree_Son[u],Top);
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==Tree_Son[u]) continue;
		if(v==fa[u]) continue;
		Find_Root_Dfs(v,v);
	}
}
int LCA(int a,int b){
	while(toop[a]!=toop[b]){
		if(Deep[toop[a]]<Deep[toop[b]])
			swap(a,b);
		a=fa[toop[a]];
	}
	if(Deep[a]<Deep[b]) return a;
	else return b;
}
signed main(){
	
	int n=read(),m=read(),s=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		adde(u,v);
		adde(v,u);
	}
	Build_Dfs(s,0);
	Find_Root_Dfs(s,s);
	while(m--){
		int a=read(),b=read();
		cout<<LCA(a,b)<<endl;
	}
	return 0;
}
2025/1/22 20:47
加载中...