从哪里跌倒从哪里爬起来,明年我会再来见你的,亲爱的百度HR。艰苦的路从LCA开始。如何求一棵树中节点的最近公共先祖,Tarjan算法,复杂度O(N)网上说O(N+E)有点不太能理解,基于深度优先搜索和并查集。
算法基本思路,从根开始深度遍历,经过任意一个节点,都要以该节点为根建立一个集合,随着深度遍历的进行,当一个节点的子节点标记被访问时(即该子节点的所有子节点都标记被访问),将该节点所在的集合和该子节点所在的集合合并,并以该节点为根。上述的过程随着深度遍历递归进行。
遍历的过程同时也是查询的过程,当遍历到的节点是其中查询的节点中的一个,判断另一个节点是否已经被访问,如果被标记访问,那LCA就是被访问节点所在集合的根节点。
算法基本思路,从根开始深度遍历,经过任意一个节点,都要以该节点为根建立一个集合,随着深度遍历的进行,当一个节点的子节点标记被访问时(即该子节点的所有子节点都标记被访问),将该节点所在的集合和该子节点所在的集合合并,并以该节点为根。上述的过程随着深度遍历递归进行。
遍历的过程同时也是查询的过程,当遍历到的节点是其中查询的节点中的一个,判断另一个节点是否已经被访问,如果被标记访问,那LCA就是被访问节点所在集合的根节点。
#include<iostream> #include<string.h> using namespace std; class node { public: int key; bool visit; node* left; node* right; node() { key=-1; visit=false; } ~node() { if(this->left!=NULL) { delete this->left; this->left=NULL; } if(this->right!=NULL) { delete this->right; this->right=NULL; } //delete this; } node(int key) { this->key=key; this->left=NULL; this->right=NULL; } }; class btree { public: node* root; node* list[10000]; btree() { this->root=NULL; } ~btree() { delete root; } void insert(node* p) { if(p->key<=0) return; if(p->key%2==1) list[(p->key)/2+(p->key)%2-1]->left=p; if(p->key%2==0) list[(p->key)/2+(p->key)%2-1]->right=p; return; } }; class union_find_set { public: int anc; int father[10000]; union_find_set() { for(int i=0;i<10000;i++) this->father[i]=-1; } int getFather(int v) { if(this->father[v]==v) { return v; } else { //getFather(this->father[v]); return getFather(father[v]); } } bool same(int x,int y) { return (getFather(x)==getFather(y)); } bool judge(int x,int y) { int fx,fy; fx=getFather(x); fy=getFather(y); if(fx==fy) false; else { father[fx]=fy; return true; } } }; union_find_set ufset; int visit[10000]; int result; void dfs(node* p,int a,int b) { ufset.father[p->key]=p->key; if(a==p->key) { if(visit[b]==1) result=ufset.getFather(b); } if(b==p->key) { if(visit[a]==1) result=ufset.getFather(a); } if(p->left!=NULL) { dfs(p->left,a,b); ufset.judge(p->left->key,p->key); } if(p->right!=NULL) { dfs(p->right,a,b); ufset.judge(p->right->key,p->key); } visit[p->key]=1; } void getLCA(node* p,int a,int b) { memset(visit,0,sizeof(visit)); dfs(p,a,b); } int main() { int a,b; btree* tree=new btree; for(int i=0;i<=14;i++) { node* n=new node(i); tree->list[i]=n; tree->insert(n); } tree->root=tree->list[0]; //cout<<tree->list[8]->left->key<<endl; while(cin>>a>>b) { for(int i=0;i<10000;i++) ufset.father[i]=-1; getLCA(tree->root,a,b); for(int i=0;i<15;i++) { //cout<<"father["<<i<<"]="<<ufset.father[i]<<endl; } //cout<<ufset.father[0]<<endl; //cout<<ufset.getFather(3)<<endl; cout<<result<<endl; } delete tree; return 0; }
发表评论
-
图的割点tarjan---zoj_1119
2011-10-24 23:00 1261http://acm.zju.edu.cn/on ... -
BFS与双向BFS---zoj_1505
2011-10-09 17:14 1676http://acm.zju.edu.c ... -
静态treap+线段树---zoj_2112
2011-09-29 23:06 1734http://acm.zju.edu ... -
NIM博弈游戏,SG函数---zoj_3084,zoj_2083
2011-09-23 23:00 1340Nim游戏是两个人进行的游戏有如下规则: ... -
多重背包--zoj_2156
2011-09-14 11:10 893首先介绍经典的三种背包问题,0-1背包,完全 ... -
模式串匹配---KMP
2011-08-31 20:49 1307朴素的的模式串匹配算法通常要在向前移动文本指针 ... -
八数码问题(A*&&双向BFS)---zoj_1217
2011-08-30 22:13 1702题目地址:http://acm.zju.edu.cn/onli ... -
ac自动机以及它上面的DFA
2011-08-08 23:04 2527AC自动机(Aho-Corasick)主要用 ... -
二分图最大匹配(匈牙利算法)--zoj1516,1525,2223
2011-07-20 22:36 1209二分图G(E,V)将点集合V分成两个部分L,R ... -
网络最大流(EK)---zoj_1734
2011-07-19 16:34 2179网络最大流是图论中的一个典型问题,为了精确的定 ... -
trie和前缀检查---zoj_2876
2011-07-13 23:03 890trie树是一种多叉树,广泛用于字典检索。如 ... -
位图bitmap
2011-07-13 21:08 948bitmap是一种广泛使用的数据结构,主要用在 ... -
LAC和RMQ的转化---zoj_3195
2011-07-12 22:35 1103我擦。。纠结了好久啊,从SF到TLE,先总结2 ... -
LAC的tarjan(离线)算法---zoj_1141
2011-07-08 17:52 1690LCA就不解释了,这里主要再次复习一下LC ... -
笛卡尔树以及treap---zoj_2243
2011-07-07 15:52 2886zoj_2243笛卡 ... -
线段染色,矩形切割,离散化---zoj_2301,zoj_1128
2011-06-24 22:32 1409染色问题:在一维坐标轴上(最右端为M),有N ... -
线段树---zoj_1610
2011-06-22 21:06 786线段树是一种二叉树的拓展,在线段树每个节点中 ... -
快速排序(qsort)
2011-06-16 17:03 799快速排序是一种高效的非稳定排序,它的基本思路 ... -
斐波那契散列
2011-06-16 16:38 3108斐波那契散列法其实是一种特殊的乘法散列,先来看乘法 ... -
强连通分支(scc)---tarjan
2011-06-15 16:17 1311本文大量 ...
相关推荐
最近公共祖先(LCA)问题在计算机科学,特别是在图论和数据结构中具有重要的应用,尤其是在树形数据结构的处理中。LCA指的是在一棵有根树中,给定两个节点u和v,找到离根最远的那个节点r,使得r既是u的祖先也是v的...
其中,PROC LCA(Latent Class Analysis)是SAS中的一个过程,用于执行潜在类别分析,这是一种统计方法,旨在从观测数据中识别出隐藏的、不可见的类别结构。PROC LCA尤其适用于处理多分类变量,它可以帮助研究人员...
【LCA词汇复杂度分析软件】是一款用于自然语言处理(NLP)的专业工具,它主要聚焦于语言的复杂度分析。LCA,全称为“Language Complexity Analysis”,此软件旨在帮助用户理解和评估文本的语言难度,这对于教育、...
**Tarjan的LCA算法详解** 最近公共祖先(Lowest Common Ancestor,简称LCA)是图论中的一个重要概念,特别是在树形结构中。在树中,两个节点的最近公共祖先指的是距离根节点最近的那个同时是这两个节点的祖先的节点...
LCA265显示器是Systeme Lauer GmbH & Co. KG公司生产的一款专业显示器,用于显示和处理用户数据。在操作这款显示器时,有时需要进行数据传输,特别是文本文件的交换,这通常涉及到与个人计算机(PC)之间的通信。...
《51单片机开发工具LCA51正式版2.06详解》 51单片机,作为微控制器领域中的经典型号,被广泛应用于各种电子设备和控制系统中。对于51单片机的开发者而言,拥有一款高效、易用的编辑器、编译器和仿真工具至关重要。...
为了满足题目要求,我将基于标题和描述部分提供的信息,对“日立LCA电气图纸”进行知识性的解释。 ### LCA型微机控制变压变频调速无机房乘客电梯的知识点 #### 电梯基本概念 - **乘客电梯**:专为运送乘客设计的...
例如,在一个树形结构中,A是B和C的LCA,D是E和F的LCA。 1. **Tarjan离线算法**: Tarjan提出了一种离线算法来解决LCA问题,使用并查集维护树结构,并通过深度优先搜索(DFS)进行预处理。每个节点u的father[u]...
关于RMQ和LCA的关系的知识,如何用RMQ和LCA的转换
【LCA51早期版本】是一款专用于模拟和开发基于MCS-51(8051)微控制器的应用程序的软件工具。这个版本是2.02,可能对于一些研究历史版本、进行兼容性测试或者对旧项目进行维护的开发者来说具有一定的价值。在本文中...
最近公共祖先(Lowest Common Ancestor,简称LCA)是图论中的一个重要概念,主要应用于树形结构的数据问题。在给定的树中,两个节点的最近公共祖先是指距离这两个节点最近的那个共同父节点。在计算机科学中,尤其是...
在IT领域,特别是数据结构和算法的设计中,"最近公共祖先"(Lowest Common Ancestor,简称LCA)是一个常见的问题。这个问题出现在许多场景中,比如计算机科学中的树形结构处理,生物信息学中的基因进化分析等。最近...
LCA系统 DB2数据库 表 修改数据状态
在IT领域,特别是数据结构和算法分析中,"LCA"是"Lowest Common Ancestor"(最近公共祖先)的缩写,这是一个经典的问题,常常出现在树形结构的处理中。给定一个树形结构和若干对节点,我们需要找出这些节点的最近...
LCA Tarjan: 实现原理 理解:离线算法,建好树后再查询,一次DFS 吧所有查询解决完。 时间复杂度:O(n+q); n个点 q次询问 补一下:链式向前星,并查集 ,Tarjan 代码 #include #include #include #include #...
生命周期评价(LCA)是一种系统性的评估方法,用于分析产品从原材料获取、生产制造、使用到最终废弃处理的整个生命周期中的环境影响。该方法源于国际标准化组织(ISO)制定的标准ISO 14040系列,它为进行生命周期...
LCA生命周期评价,LCA生命周期评价课件,LCA生命周期评价PPT
LCA 中文教程,内部资料--产品结构管理,还不错啊,可以看下
数据泄密(泄露)防护(Data leakage prevention, DLP),又称为“数据丢失防护”(Data Loss prevention, DLP),有时也称为“信息泄漏防护”(Information leakage prevention, ILP)。数据泄密防护(DLP)是通过一定的...