求助,倍增LCA
  • 板块题目总版
  • 楼主渡鸦2007
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/5/7 20:34
  • 上次更新2023/11/4 23:34:41
查看原帖
求助,倍增LCA
385748
渡鸦2007楼主2021/5/7 20:34

题面

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define re register
int read()
{
	register int ans=0;
	char ch;
	bool flag=0;
	while(1)
	{
		ch=getchar();
		if (ch>='0'&&ch<='9')
		{
			break;
		}
		if (ch=='-')
		{
		   flag=1;
		}
	}
	while(1)
	{
		ans=ans*10+ch-'0';
		ch=getchar();
		if (ch<'0'||ch>'9')
		{
			break;
		}
	}
	if (flag==1)
	{
	   ans*=-1;
	}
	return ans;
}
struct line
{
	int fa,son,nxt;
}line[200010];
int head[100100];
int max_log;
int cnt;
void add(int f,int s)
{
	line[++cnt].nxt =head[f];
	line[cnt].fa =f;
	line[cnt].son =s;
	head[f]=cnt;
}
int deep[100100];//深度
int elder[100010][22];//祖先
void pre(int now,int old)//预处理
{
	deep[now]=deep[old]+1;
	//elder[now][0]=old;
	for (re int i=0;i<=max_log;++i)
	{
		elder[now][i+1]=elder[ elder[now][i] ][i];
	}
	for (re int i=head[now];i!=0;i=line[i].nxt )
	{
		int son=line[i].son ;
		if (son==old)
		{
			continue;
		}
		else
		{
			elder[son][0]=now;
			pre(son,now);
		}
	}
}
int lca(int a,int b)
{
	if (deep[a]<deep[b])
	{
		swap(a,b);
	}
	for (re int i=max_log;i>=0;--i)
	{
		if (deep[ elder[a][i] ] >= deep[b])
		{
			a=elder[a][i];
			if (a==b)
			{
				return deep[a];
			}
		}
	}
	for (re int i=max_log;i>=0;--i)
	{
		if (elder[a][i]!=elder[b][i])
		{
			a=elder[a][i];b=elder[b][i];
		}
	}
	return deep[elder[a][0]];
}
int main()
{
	//freopen("1552:【例 1】点的距离.in","r",stdin);
	//freopen("1552:【例 1】点的距离.out","w",stdout);
	int n;n=read();
	max_log=log(n)+1;//max_log=20;
	for (re int i=1;i<n;++i)
	{
		int a,b;a=read();b=read();
		add(a,b);
		add(b,a);
	}
	pre(1,0);
	int ask=read();
	for (re int t=1;t<=ask;++t)
	{
		int a,b;a=read();b=read();
		int ans=deep[a]+deep[b]-2*lca(a,b);
		printf("%d\n",ans);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}


2021/5/7 20:34
加载中...