LCA 问题

LCA

tarjan


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
const int N=5e5+1145;
int lg[N+100];
int n,m,s;
int fa[N],ans[N];
bool vis[N];
struct Edge{
	int to,nex=0,num=0;
}edge[4*N],query[4*N];
int head[N],cnt;
void add_edge(int x,int y){
	edge[++cnt].to=x;
	edge[cnt].nex=head[y];
	head[y]=cnt;
	edge[++cnt].to=y;
	edge[cnt].nex=head[x];
	head[x]=cnt;
	return;
}
int head_query[N],cnt_query;
void add_query(int x,int y,int num){
	query[++cnt_query].to=x;
	query[cnt_query].nex=head_query[y];
	query[cnt_query].num=num;
//	cout<<x<<" "<<y<<" "<<num<<endl;
	head_query[y]=cnt_query;
	query[++cnt_query].to=y;
	query[cnt_query].nex=head_query[x];
	query[cnt_query].num=num;
	head_query[x]=cnt_query;
	return;
}
int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void tarjan(int pos){
	vis[pos]=1;
	for(int i=head[pos];i!=0;i=edge[i].nex){
		int point=edge[i].to;
//		cout<<pos<<":"<<point<<endl;
		if(!vis[point]){
			tarjan(point);
			fa[point]=pos;
		}
	}
//	cout<<pos<<endl;
	for(int i=head_query[pos];i!=0;i=query[i].nex){
		int point=query[i].to;
		if(vis[point]){
			ans[query[i].num]=find(point);
		}
	}
	return;
}
signed main(){
//	IOS
//	freopen("P3379_1.in","r",stdin);
	cin>>n>>m>>s;
	for(int i=1;i<=n-1;i++){
		int x,y;
		cin>>x>>y;
		add_edge(x,y);
		fa[i]=i;
	}
	fa[n]=n;
	for(int i=1;i<=m;i++){
		int x,y;
		cin>>x>>y;
		add_query(x,y,i);
	}
	tarjan(s);
	for(int i=1;i<=m;i++){
        cout <<ans[i]<< endl;
    }
	return 0; 
}

倍增

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
const int N=5e5+1145;
int lg[N+100];
int n,m,s;
struct Edge{
	int pos,nex=0;
}edge[4*N];
int head[N],cnt;
int deep[N],fa[N][20];
void add_edge(int x,int y){
	edge[++cnt].pos=x;
	edge[cnt].nex=head[y];
	head[y]=cnt;
	edge[++cnt].pos=y;
	edge[cnt].nex=head[x];
	head[x]=cnt;
	return;
}
void init(){
	//lg初始化 
	for(int i=2;i<=N;i++){
		lg[i]=lg[i>>1]+1;
	}
	//bfs
	queue<int>que;
	que.push(s);
	deep[s]=1; 
	while(!que.empty()){
		int x=que.front();
		que.pop();
		int nex=head[x];
		while(nex){
			int pos=edge[nex].pos;
			if(!deep[pos]){
				que.push(edge[nex].pos);
				deep[pos]=deep[x]+1;
				fa[pos][0]=x;
			}
			nex=edge[nex].nex;
		}
	}
	//倍增表
	fa[s][0]=-1;
	for(int i=1;i<=lg[N];i++){
		fa[s][i]=-1;
		for(int j=1;j<=n;j++){
			if(fa[j][i-1]!=-1)fa[j][i]=fa[fa[j][i-1]][i-1];
			else fa[j][i]=-1;
		}
	} 
}
signed main(){
	IOS
//	freopen("P3379_1.in","r",stdin);
	cin>>n>>m>>s;
	for(int i=1;i<=n-1;i++){
		int x,y;
		cin>>x>>y;
		add_edge(x,y);
	}
	init();
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		if(a==b){
			cout<<a<<endl;
			continue;
		}
		if(deep[a]<deep[b])
			swap(a,b);
		while(deep[a]!=deep[b]){
			a=fa[a][lg[deep[a]-deep[b]]];	
		}
		if(a==b){
			cout<<a<<endl;
			continue;
		}
		for(int i=lg[deep[a]];i>=0;i--){
			if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
		}
		cout<<fa[a][0]<<endl;
	}
	return 0; 
}
posted @ 2025-11-26 13:53  10mbps_十兆網路  阅读(9)  评论(0)    收藏  举报