倍增LCA求调
查看原帖
倍增LCA求调
992303
fedcba楼主2024/10/24 22:01
#include<bits/stdc++.h>
using namespace std;
vector<long long int> v[500010];
long long int f[500010][50],depth[500010],vis[500010],lg[100];
long long int lowbit(long long int x)
{
	return x&-x;
}
int LCA(int a,int b)
{
	if(depth[b]>depth[a])
	{
		swap(a,b);
	}
	long long int x=depth[a]-depth[b],cnt=0;
	while(depth[a]>depth[b])
	{
		long long int lowb=lowbit(x)-1;//lowbit求最后一个1在第几位 
		a=f[a][lowb];
		x-=(1<<lowb);//减去最后一个1 
	}
	if(a==b)
	{
		return a;
	}
	for(long long int lowb=lg[depth[a]];lowb>=1;lowb--)
	{
		if(f[a][lowb]!=f[b][lowb])
		{
			a=f[a][lowb];
			b=f[b][lowb];
		}
	}
	return f[a][0];
}
void DFS(long long int t,long long int fa)
{
	f[t][0]=fa;
	depth[t]=depth[fa]+1;
	for(long long int i=1;i<=lg[depth[t]];i++)
	{
		f[t][i]=f[f[t][i-1]][i-1];
	}
	vis[t]=1;
	for(long long int i=0;i<v[t].size();i++)
	{
		if(!vis[v[t][i]])
		{
			DFS(v[t][i],t);
		}
	}
	vis[t]=0;
	return;
}
int main()
{
	int n,m,s;
	cin>>n>>m>>s;
	for(int i=1;i<n;i++)
	{
		int u,w;
		cin>>u>>w;
		v[u].push_back(w);
		v[w].push_back(u);
	}
	for(int i=1;i<=n;i++)
	{
		lg[i]=lg[i-1];
		if(i==(1<<lg[i-1]))
		{
			lg[i]++;
		}
	}
	DFS(s,0);
	for(int i=1;i<=m;i++)
	{
		int a,b;
		cin>>a>>b;
		cout<<LCA(a,b)<<'\n';
	}
	return 0;
}
2024/10/24 22:01
加载中...