LCA

//方法一 
vector<int>G[MAX_N];//输入 图的邻接表 
int root;//根节点
int parent[MAX_N];//父亲节点 
int depth[MAX_N];//节点深度 
void dfs(int v,int p,int d)
{
	parent[v]=p;
	depth[v]=d;
	for(int i=0;i<G[v].size();i++)
	if(G[v][i]!=p)
	dfs(G[v][i],v,d+1);
} 
void init()
{
	dfs(root,-1,0);
}
int LCA(int u,int v)
{
	while(depth[u]>depth[v])
	u=parent[u];
	while(depth[v]>depth[u])
	v=parent[v];
	while(u!=v)
	{						
		u=parent[u];
		v=parent[v];
	}
}

//方法二
vector<int>G[MAX_N];
int root;
int parent[MAX_LOG_N][MAX_N]; 
int depth[MAX_N];
void dfs(int v,int p,int d)
{
	parent[0][v]=p;
	depth[v]=d;
	for(int i=0;i<G[v].size();i++)
	if(G[v][i]!=p)
	dfs(G[v][i],v,d+1);
}
void init(int V)
{
	dfs(root,-1,0);
	for(int k=0;k+1<MAX_LOG_N;k++)
	{
		for(int v=0;v<V;v++)
		{
			if(parent[k][v]<0)
			parent[k+1][v]=-1;
			else
			parent[k+1][v]=parent[k][parent[k][v]];
		}
	}
}
int LCA(int u,int v)
{
	if(depth[u]>depth[v])
	swap(u,v);
	for(int k=0;k<MAX_LOG_N;k++)
	{
		if(depth[v]-depth[u]>>k&1)
		v=parent[k][v];
	}
	if(u==v)
	return u;
	for(int k=MAX_LOG_N;k>=0;k--)
	{
		if(parent[k][u]!=parent[k][v])
		{
			u=parent[k][u];
			v=parent[k][v];
		}
	}
	return parent[0][u];
}

//方法三
vector<int>G[MAX_N];
int root;
int vs[MAX_N*2-1];  //dfs访问的顺序
int depth[MAX_N*2-1];
int id[MAX_N];   // 各个顶点在vs中首次出现的下标
void dfs(int v,int p,int d,int &k)
{
	id[v]=k;
	vs[k]=v;
	depth[k++]=d;
	for(int i=0;i<G[v].size();i++)
	{
		if(G[v][i]!=p)
		{
			dfs(G[v][i],v,d+1,k);
			vs[k]=v;
			depth[k++]=d;
		} 
	}	
} 
void init(int V)
{
	int k=0;
	dfs(root,-1,0,k);
	rmq_init(depth,V*2-1);
}
int LCA(int u,int v)
{
	return vs[query(min(id[u],id[v]),max(id[u],id[v])+1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值