poj1330——Nearest Common Ancestors

本文介绍了一种求解最近公共祖先(LCA)问题的离线算法,并提供了详细的递归实现过程。通过构建并查集来维护节点间的祖先关系,使用颜色标记辅助判断查询对的LCA节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LCA离线算法,递归求解。详见:http://blogold.chinaunix.net/u3/105033/showart_2238641.html

伪代码:

LCA(u)
{
Make-Set (u);
ancestor[Find-Set (u)]=u;
for every child v of u
{
LCA(v);
Union (u,v);
}
color [u]=colored;
for every questioned pair (u,v)
{
if color[v]==colored
{
the lca of (u,v) is ancestor[Find-Set (v)];
}
}
}

#include<iostream> #include<cstdio> using namespace std; int tree[10001][100],in[10001],p[10001]; int cas,s,t; int n,q1,q2; bool vis[10001]; void Make_Set(int t) { p[t]=t; } int Find(int t) { if(t!=p[t]) p[t]=Find(p[t]); return p[t]; } void Union(int u,int v) { p[v]=u; } void LCA(int root) { Make_Set(root); int i; for(i=1;i<=tree[root][0];i++) { LCA(tree[root][i]); Union(root,tree[root][i]); } vis[root]=1; if(root==q1&&vis[q2]) printf("%d\n",p[Find(q2)]); else if(root==q2&&vis[q1]) printf("%d\n",p[Find(q1)]); } int main() { scanf("%d",&cas); while(cas--) { int i; memset(tree,0,sizeof(tree)); memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&s,&t); tree[s][++tree[s][0]]=t; in[t]++; } scanf("%d%d",&q1,&q2); for(i=1;i<=n;i++) { if(in[i]==0) break;//根节点 } LCA(i); } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值