LCA学习心得

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Patrickpwq/article/details/79967873

嗯...今天只更新倍增版的 明天看写不写st表 树剖 tarjan等其他实现方式

1.写在前面

其实倍增版lca很好理解 代码看着也不恶心 但据说常数大 跑得慢(相比其他的几种方式)

2.细节一----关于邻接表的处理

无向图记得add两次就好了.....以及edge数组大小——边的两倍

    细节二----fa[now][i]=fa[fa[now][i-1]][i-1];

 这个比较重要由于不是二叉树 因此无法直接*2

fa[now][i-1]是now往上跳2^(i-1)的位置

由于2^i=2^(i-1)+2^(i-1) 因此再跳2^(i-1)就行了

(fa[now][i-1]之前必定处理过,fa[fa[now][i-1]][i-1]也是)

   然后应该没啥了..其他细节应该没什么了 看看我的注释就好了

#include<bits/stdc++.h>
using namespace std;
int n,m,s,tot; 
int first[500005],deepth[500005],fa[500005][25];
struct node
{
	int to;
	int next;
}edge[500005*2];
int read()
{
	int k=0;
	char ch=getchar();
	while(!isdigit(ch))	ch=getchar();
	while(isdigit(ch))	
	{
		k=k*10+ch-'0';
		ch=getchar();
	}
	return k;
}
inline void add(int x,int y)
{
	++tot;
	edge[tot].to=y;
	edge[tot].next=first[x];
	first[x]=tot;
}
void dfs(int now,int father)
{
	deepth[now]=deepth[father]+1;
	fa[now][0]=father;	//2的0次方是1 距离1当然就是自己的爸爸
	for(int i=1;(1<<i)<=deepth[now];i++)	//找now往上的fa数组 
	{
		fa[now][i]=fa[fa[now][i-1]][i-1];	//不是二叉树 因此无法直接*2	//fa[now][i-1]是now往上跳2^i-1的位置
		// 由于2^i=2^(i-1)+2^(i-1) 因此再跳2^(i-1)就行了 
	} 
	for(int i=first[now];i;i=edge[i].next)
	{
		int vis=edge[i].to;
		if(vis!=father)	dfs(vis,now);
	}
}
int lca(int x,int y)
{
	if(deepth[x]<deepth[y])	swap(x,y);	//保证x的深度总是大的那个 
	for(int i=21;i>=0;--i)
	{
		if(deepth[fa[x][i]]>=deepth[y])	x=fa[x][i];	//x往上跳 直到跳到一个点 使得这个点的深度=y的深度(y)(由于2^i相加可以到达任何点) 
	}
	if(x==y)	return x; 
	for(int i=21;i>=0;--i)
	{
		//两个节点最近公共祖先以上的根必定也是这两个点的祖先 
		if(fa[x][i]!=fa[y][i])
		{
			x=fa[x][i];
			y=fa[y][i];
		}
		//使x,y成为最浅的满足deepth[x]==deepth[y],且x!=y的两个点
		//此时的x,y 不管i为多少 fa[x][i]一定等于fa[y][i] 
	}
	return fa[x][0];
} 
int main()
{
//	freopen("wordin.in","r",stdin);
	n=read();
	m=read();
	s=read();
	for(int i=1;i<=n-1;i++)
	{
		int x,y;
		x=read();
		y=read();
		add(x,y);
		add(y,x);
	}
	dfs(s,0);	//默认起点的根为0
	for(int i=1;i<=m;i++)
	{
		int x,y;
		x=read();
		y=read();
		printf("%d\n",lca(x,y));
	}
	return 0; 
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页