LAC(least common Ancestor)算法

LAC 算法的定义:

      对于树 T 的两个节点 u  v满足最近公共祖先的 LAC(T,u,v) 存在一顶点 x 满足 x 是 u 和 v 的公共 祖先 ,且  x 的在树中深度最大。

LAC 的算法思想是:并查集 + dfs

详细过程代码:(给出详细的注解)

#include<iostream>  
#include<vector>  
using namespace std;  

const int MAX=10001;  
int f[MAX];  // 用于记录节点 的父节点
int r[MAX];  // 秩 用于 并查集时的优化其目的是在并查集中使得树的深度尽量最小。
int indegree[MAX]; //保存每个节点的入度  
int visit[MAX];  // 注释 i 节点是否被访问
vector<int> tree[MAX],Qes[MAX];  
int ancestor[MAX];  // ancertor[i] 其中 i 为集合的代号, ancertor[i] 为此集合的 Least Common Ancestor

void init(int n)  
{  
	for(int i=1;i<=n;i++)  
	{  	
		r[i]=1;  
		f[i]=i;  
		indegree[i]=0;  
		visit[i]=0;  
		ancestor[i]=0;  
		tree[i].clear();  
		Qes[i].clear();  
	}  
	
}  

int find(int n)  
{  
	if(f[n]==n)  {
		return n;  
	}
	else  {
		f[n]=find(f[n]); 
	}
	return f[n];  
}//查找函数,并压缩路径  

int Union(int x,int y)  
{  
	int a=find(x);  // x 节点 所在 集合的代表
	int b=find(y);  // y 节点所在集合的代表
	if(a==b) { 
		return 0;  
	}
	//相等的话,x向y合并  
	else if(r[a]<=r[b])  
	{  
		f[a]=b;  
		r[b]+=r[a];  
	}  
	else  
	{  
		f[b]=a;  
		r[a]+=r[b];  
	}  
	return 1;  
}//合并函数,如果属于同一分支则返回0,成功合并返回1  

void LCA(int u)  
{  
	
	ancestor[u]=u;  // 记录 u 的最近祖先
	int size = tree[u].size();// 得到 u 的 的子节点 并以递归 调用
	for(int i=0;i<size;i++)  
	{  
		LCA(tree[u][i]);  // 递归 调用
		Union(u,tree[u][i]);  // 当子节点 调用完成 将 节点 u, tree[u][i] 并日一个集合
		ancestor[find(u)]=u; //记录 结合的最近祖先
	}  
	visit[u]=1; // 标记 u 已经被访问
	size = Qes[u].size();  
	for( i=0;i<size;i++)  
	{  
		//如果已经访问了 问题 节点,就可以返回结果了.  
		if(visit[Qes[u][i]]==1)  
		{  
			cout<<ancestor[find(Qes[u][i])]<<endl;  
			return;  
		}  
	}  
}  
int main()  
{  
	int cnt;  
	int n;  
	cin>>cnt;  
	while(cnt--)  
	{  
		cin>>n;
		init(n);  
		int s,t;  
		for(int i=1;i<n;i++)  
		{  
			cin>>s>>t;  // 输入 2  个 想通的 顶点 组成边 (s ,t)
			tree[s].push_back(t);  
			indegree[t]++;  // 记录 t 的入度
		}  

		//这里可以输入多组询问  
		cin>>s>>t;  // 
		//相当于询问两次  
		Qes[s].push_back(t);  
		Qes[t].push_back(s);  

		for(i=1;i<=n;i++)  
		{  
			//寻找根节点  ( 可能存在多个 根节点)
			if(indegree[i]==0)  
			{  
				LCA(i);  
				break;  
			}  
		}  
	}  
	return 0;  
}  


你可能感兴趣的:(LAC(least common Ancestor)算法)