LCA(least common ancestors)最近公共祖先
2015-03-12 20:46
309 查看
/article/2013599.html
对于有根树T的两个节点u、v,最近公共祖先LCA(u,v)表示一个节点x,满足x是u,v的祖先,且x的深度尽可能大
如果把树看成图,就是求到u,v的最短距离
时间复杂度为O(n+q),n为树的节点数,q为询问次数
离线算法
Trajan算法基于深度优先搜索,对于新搜索到的一个节点,首先创建由这个节点构成的集合,再对当前节点的每一个子树进行搜索,每搜索完一棵子树,则可确定子树内的LCA询问都已解决。其他的LCA询问的结果必然在这个子树之外,这时把子树所形成的集合与当前节点的集合合并,并将当前节点设为这个集合的祖先。之后继续搜索下一棵子树,直到当前节点的所有子树搜索完。这时把当前节点也设为已被检查过的,同时可以处理有关当前节点的LCA询问。
代码流程:
算法:Tarjan_Dfs(u),对u为根的子树进行DFS
输入:树u和LCA查询集合Q
输出:Q的答案
(1) 创建并查集合u
(2) 对于(u,v)属于Q,如果v已经被标记,则Ancestor(u,v) <-v为v所在集合的根
(3) 对于u的每一个儿子v
1.递归调用Tarjan_Dfs(v)
2.合并u和v所在的集合,设根为u
(4)标记u
对于有根树T的两个节点u、v,最近公共祖先LCA(u,v)表示一个节点x,满足x是u,v的祖先,且x的深度尽可能大
如果把树看成图,就是求到u,v的最短距离
时间复杂度为O(n+q),n为树的节点数,q为询问次数
离线算法
Trajan算法基于深度优先搜索,对于新搜索到的一个节点,首先创建由这个节点构成的集合,再对当前节点的每一个子树进行搜索,每搜索完一棵子树,则可确定子树内的LCA询问都已解决。其他的LCA询问的结果必然在这个子树之外,这时把子树所形成的集合与当前节点的集合合并,并将当前节点设为这个集合的祖先。之后继续搜索下一棵子树,直到当前节点的所有子树搜索完。这时把当前节点也设为已被检查过的,同时可以处理有关当前节点的LCA询问。
代码流程:
算法:Tarjan_Dfs(u),对u为根的子树进行DFS
输入:树u和LCA查询集合Q
输出:Q的答案
(1) 创建并查集合u
(2) 对于(u,v)属于Q,如果v已经被标记,则Ancestor(u,v) <-v为v所在集合的根
(3) 对于u的每一个儿子v
1.递归调用Tarjan_Dfs(v)
2.合并u和v所在的集合,设根为u
(4)标记u
[code]const int maxn=10000;//节点数 using namespace std; int f[maxn],size[maxn],in[maxn],vis[maxn],ance[maxn];//集合,名次,入度,标记,祖先 vector<int> node[maxn],que[maxn];//边表,询问 void Init(){ for(int i=0;i<maxn;++i){ node[i].clear(); que[i].clear(); size[i]=1; f[i]=i; } } int find(int x){ return f[x]==x? x:f[x]=find(f[x]); } void Union(int a,int b){//按名次合并 int x=find(a); int y=find(b); if(size[x]<=size[y]){ f[x]=y; size[y]+=size[x]; }else{ f[y]=x; size[x]+=size[y]; } } void LCA(int rt){//dfs int sz=node[rt].size(); ance[rt]=rt;//创建集合 for(int i=0;i<sz;++i){ LCA(node[rt][i]);//递归调用子树 Union(rt,node[rt][i]);//将子树与父节点合并 ance[find(node[rt][i])]=rt;//将子树所在的集合的祖先指向根 } vis[rt]=1; sz=que[rt].size(); for(int i=0;i<sz;++i){ if(vis[que[rt][i]]){ printf("%d\n",ance[find(que[rt][i])]);//v所在集合的根 } } } int main() { for(int i=0;i<n;++i){ if(in[i]==0){LCA(i);break;}//找到根节点 } return 0; }
相关文章推荐
- LCA-Least Common Ancestors(最近公共祖先)
- 最近公共祖先(least common ancestors,LCA)
- 最近公共祖先 Least Common Ancestors(LCA)算法 --- 与RMQ问题的转换
- LCA问题——最近公共祖先(Least Common Ancestors)
- LCA最近公共祖先(least common ancestors)
- 最近公共祖先(Least Common Ancestors,LCA)问题详解
- LCA最近公共祖先(least common ancestors)
- LCA(Least Common Ancestors)最近公共祖先
- LCA(Least Common Ancestors)最近公共祖先问题
- 最近公共祖先(least common ancestors algorithm)
- POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)
- 最近公共祖先(least common ancestors algorithm)
- poj1470 Closest Common Ancestors LCA(最近公共祖先)
- POJ1330 Nearest Common Ancestors(在线倍增,离线Tarjan,最近公共祖先LCA)
- POJ - 1330 Nearest Common Ancestors(LCA最近公共祖先 朴素算法&倍增法)
- POJ1330 Nearest Common Ancestors【最近公共祖先】【Tarjan-LCA算法】
- 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)
- 最近公共祖先(Least Common Ancestors)
- 最近公共祖先(Least Common Ancestors)
- 最近公共祖先(Least Common Ancestors)