树剖subtask2的#1#2T了,求助QWQ
查看原帖
树剖subtask2的#1#2T了,求助QWQ
637073
wujingfey楼主2023/8/8 21:03
#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int res=0,f=1;char c=getchar();
	while(c<'0'||'9'<c){
		if(c=='-') f=-1;
		c=getchar();
	}
	while('0'<=c&&c<='9'){
		res=(res<<3)+(res<<1)+c-'0';
		c=getchar();
	}
	return res*f;
}
const int N=5e5+10;
int n,m,s;
vector<int> e[N];
int fa[N],dep[N],son[N],sz[N],top[N];
//fa记录父节点,dep记录深度,son记录重儿子,sz记录字数大小,top记录所在重链的顶点 
void dfs1(int u,int fat){//处理出fa、dep、son、sz数组 
	fa[u]=fat,dep[u]=dep[fat]+1,sz[u]=1;//信息初始化
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==fat) continue;
		dfs1(v,u);
		sz[u]+=sz[v];//统计子树大小 
		if(son[u]<sz[v]) son[u]=v;//如果这个儿子比当前儿子大,更新重儿子 
	} 
}
void dfs2(int u,int t){ 
	top[u]=t;//记录链头
	if(!son[u]) return;//无重儿子则返回
	dfs2(son[u],t);//继续搜索重儿子
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==fa[u]||v==son[u]) continue;//搜索不是重链的儿子们
		dfs2(v,v);//开始新的链 
	}
}
int lca(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]>=dep[top[y]]) x=fa[top[x]];
		else y=fa[top[y]];//优先把深度深的往上跳到链头的父节点 
	}
	return dep[x]<dep[y]?x:y;//返回深度低的节点 
}
int main(){
	n=read(),m=read(),s=read();
	for(int i=1;i<n;i++){
		int a=read(),b=read();
		e[a].push_back(b);
		e[b].push_back(a);
	}
	dfs1(s,0);
	dfs2(s,s);
	for(int i=1;i<=m;i++){
		int a=read(),b=read();
		printf("%d\n",lca(a,b));
	}
	return 0;
} 
2023/8/8 21:03
加载中...