最低公共祖先_51CTO博客
题意:给定一棵有根树T,给出若干个查询lca(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根)。通常有以下几种算法:在线算法,每次读入一个查询,处理这个查询,给出答案。离线算法,一次性读入所有查询,统一进行处理,给出所有答案。在线:倍增(基于二分搜索):基本思想就是让u和v同时走到同一高度,然后再一起一步
转载 2023-06-18 20:33:15
59阅读
题目描述:给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。输入:输入可能包含多个测试样例。 对于每个测试案例,输入的第一行为一个数n(0#include #include using namespace std;struct Node{ int x; struct Node *left; struct Node *right;};int path1[10000],path2[10000];int top1 = -1,top2 = -1;void createTree(Node *&root){ int x; scanf("%d",&x); if(!
转载 2013-07-03 20:07:00
33阅读
2评论
题目:求一棵普通树上两个结点的最低公共祖先分析:求出到这两个结点的路径,然后求路径的最后一个公共结点即可。实现:bool GetNodePath(TreeNode* pRoot,TreeNode* pNode,list<TreeNode*>&path)  //求结点的路径 {     if
原创 2014-12-10 19:20:03
626阅读
洛谷P3379 【模板】最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 输入输出格式 输入格式: 第一行包含三个正整数$N$、$M$、$S$,分别表示树的结点个数、询问的个数和树根结点的序号。 接下来$N 1$行每行包含两个正整数$x$、$y$,表示
转载 2018-06-06 15:30:00
93阅读
2评论
基本概念 最近公共祖先:在一棵有根树中,一对结点$(x, y)$的最近公共祖先(\(LCA\),\(Lowest \ Common \ Ancestor\))定义为它们深度最大的$x, y$共同的祖先结点,即距离$x$和$y$最近的公共祖先结点。 算法思路 原始算法 显然,我们可以从结点$x$开始向 ...
转载 2021-07-24 23:21:00
100阅读
摘要:本文主要介绍了解决LCA(最近公共祖先问题)的两种算法,分别是离线Tarjan算法和在线算法,着重展示了在具体题目中的应用细节。  最近公共祖先是指对于一棵有根树T的两个结点u和v,它们的LCA(T,u,v)表示一个结点x,满足x是u和v的公共祖先且x深度尽可能的大(也即最近)。  求最近公共祖先有两种方法:一种是离线求解算法,也就是将询问全部存起来,处理完之后一次回答所有询问;另一种方法就
1062 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 1062 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其中,但这是为什么呢? “为什么呢?”小H
转载 2018-07-26 16:30:00
115阅读
2评论
情形1:树是搜索二叉树思路:从树的根节点開始遍历,假设根节点的值大于当中一个节点,小于另外一个节点,则根节点就是最低公共祖先。否则假设根节点的值小于两个节点的值,则递归求根节点的右子树,假设大于两个节点的值则递归求根的左子树。假设根节点正好是当中的一个节点,那么说明这两个节点在一条路径上。所以最低公...
转载 2016-01-19 14:21:00
111阅读
2评论
最近公共祖先(\(\rm Least\,Common\,Ancestors\)),简记为 \(\rm LCA\)。顾名思义就是一棵树中的某两个节点的公共祖先中离他们最近,即深度最大的那个。 举个例子: 上图中 \(8\) 和 \(6\) 的 LCA 就是 \(1\)。 那么怎么求 LCA 呢? 1 ...
转载 2021-08-07 18:03:00
114阅读
2评论
考虑一个问题:任意两个点的$LCA$要么是他们的某个祖先,要么是其中某个点。 那么可以分类讨论。 其实可以发现,当某个点被改为黑色后,他的所有祖先对除了他所在的子树的节点的贡献只需计算一遍,就是说,如果之前某个祖先已经对另外的子树的节点取过$max$了,意思就是说他已经作为可能的$LCA$对他们贡献 ...
转载 2021-08-03 21:07:00
118阅读
2评论
[模板]https://www.luogu.com.cn/problem/P3379 const int N = 5e5 + 50,M = 1e6 +50; int h[N],e[M],ne[M],idx; void add(int a,int b) { e[idx]=b,ne[idx]=h[a], ...
转载 2021-09-06 20:29:00
28阅读
2评论
有很多方法,是一组题目。 如果是二叉搜索树,那么比较两个节点跟root,都大或者都小的话,都在一边,否则各自一边。 如果是由回溯指针,可以演变成找链表第一个共同节点。 如果普通树,可以用递归的方法,左子树和右子树分别返回。 也可以借助辅助内存,把路径记下来,然后比较路径,得到最低公共祖先
转载 2017-02-21 13:28:00
128阅读
2评论
囧啊囧。lca的求法太多了倍增,tarjan,st,lct,hld....后边三个我就不写了,其中st我没写过,估计用不上,在线用倍增,离线用tarjan就行了。嗯。第一种,倍增(O(nlogn)~O(logn),在线):倍增的思想用在树上,即可以求出lca。我们维护二维数组,f[i][j],表示i...
转载 2021-08-11 14:18:25
102阅读
传送门 考场上坚持认为树剖可做,于是几乎爆零 别一直坚持一个思路!就算这个思路很可能是对的但自己不会写也要及时换思路! 但正解思路跟考场上想的思路真的很像,连开的数组都一样 考虑一个点被染黑时可能更新哪些白点的答案 开一个bool two[]和一个int son[],两个标记不共存,上翻修改 然后我 ...
转载 2021-08-03 21:45:00
80阅读
今天终于把倍增的LCA搞懂了!尽管周测都没写,尽管lca其实很简单,但这也是进度君的往前一点点的快乐。学渣的呻吟。 倍增的lca其实关键就在于二进制的二进制的拆分(显然是两次的拆分,很奇妙,懂二进制的自然不觉得什么)。把最关键的地方在这里列举一下吧: 1.f[fa][i]=f[f[fa][i-1]]
转载 2018-09-21 21:32:00
73阅读
2评论
最近公共祖先:在一个有根树中,结点u、v的最近公共祖先是满足是u,v的公共祖先并且深度尽可能大的结点。 1、倍增法 首先如果两个点的深度如果不同,将深度较大的点跳到与深度较小的点一样的深度,再同时向上跳,首次相遇时即为最近公共祖先。 2、树剖法size x为以x为结点的子树的结点的个数 每个结点和它
转载 2017-05-01 21:11:00
104阅读
2评论
最近公共祖先(LCA) 首先是最近公共祖先的概念 (什么是最近公共祖先? ): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共祖先节点。 换句话说,就是两个点在这棵树上距离最近的公共祖先节点 朴素算法 求最近公共祖先的方法有很多,想最简 ...
转载 2021-08-20 15:09:00
230阅读
2评论
方法1:向上标记法 时间复杂度:\(O(n)\) 待查询点为a和b,首先从a点向根节点进行搜索,将路径上的点进行标记, 再从b点向根节点进行搜索,同时检测路径上的点是否被标记过,第一次检测到的点即为a,b两点的最近公共祖先 方法2:倍增 时间复杂度 预处理:\(O(nlog_n)\) 查询: \(O ...
转载 2021-09-04 14:42:00
209阅读
2评论
(原标题:最近公共祖先学习笔记) 其实是假的。 这个,老早就学过了,但是显然由于当时理解得不透彻,很快就遗忘了。 今天,做了一份模拟试题,第一题就是LCA,汗!没办法,只好温习,终于理解透彻了。 最近公共祖先,顾名思义,就是指求树上两个点的第一个公共祖先,或者说是深度最大的公共祖先。 求这个有什么用呢? 一个常见的用途就是求两点简单路径。 有人可能说,这不简单吗?我们把两个点调整到同一个高度,然后
原创 2022-11-18 11:00:43
99阅读
最近公共祖先问题: 情况1:二叉树是个二叉查找树,且root和两个节点的值(a, b)已知。如果该二叉树是二叉查找树,那么求解LCA十分简单。基本思想为:从树根开始,该节点的值为t,如果t大于t1和t2,说明t1和t2都位于t的左侧,所以它们的共同祖先必定在t的左子树中,从t.left开始搜索;如果t小于t1和t2,说明t1和t2都位于t的右侧,那么
原创 2023-04-25 09:54:01
24阅读
  • 1
  • 2
  • 3
  • 4
  • 5