概念: 对于有根树T的两个节点u,v,最近公共祖先LCA(T, u, v)表示一个节点 x, 满足 x 是 u , v 的祖先且 x 的深度尽可能的大.即从 u 到 v 的路径一定经过点 x. 算法: 解决LCA问题比较经典的是Tarjan - LCA 离线算法,还有另外一种方法,是经过一系列处理将LCA问题转化为和数据结构有关的RMQ问题加以解决.这里只阐述下Tarjan - LCA 算法. Tarjan - LCA算法: 此算法基于 DFS 框架,每搜到一个新的节点,就创建由这个节点构成的集…
摘要: 本文主要介绍了解决LCA(最近公共祖先问题)的两种算法,分别是离线Tarjan算法和在线算法,着重展示了在具体题目中的应用细节. 最近公共祖先是指对于一棵有根树T的两个结点u和v,它们的LCA(T,u,v)表示一个结点x,满足x是u和v的公共祖先且x深度尽可能的大(也即最近). 求最近公共祖先有两种方法:一种是离线求解算法,也就是将询问全部存起来,处理完之后一次回答所有询问:另一种方法就是在线求解算法,对于每次询问,动态地回答. 离线算法Tarjan Tarjan算法就是利用深度优先搜索…
题意: 给定一棵有根树T,给出若干个查询lca(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根).通常有以下几种算法: 在线算法,每次读入一个查询,处理这个查询,给出答案. 离线算法,一次性读入所有查询,统一进行处理,给出所有答案. 在线: 倍增(基于二分搜索): 基本思想就是让u和v同时走到同一高度,然后再一起一步步往上走. 将父亲结点的父亲结点利用起来,依次计算,便可以得到从当前结点向上走2k步所到…
树上倍增是求解关于LCA问题的两个在线算法中的一个,在线算法即不需要开始全部读入查询,你给他什么查询,他都能返回它们的LCA. 树上倍增用到一个关键的数组F[i][j],这个表示第i个结点的向上2^j层的结点.在RMQ-ST中用救是这样的数组. 在树上倍增中也是关键点. 如在上图中,我们要找结点8和7的LCA,从途中我们可以看出是3(这句估计是废话).采用倍增的思想是这样的 首相判断结点U和V是否在同一层次,即是否深度相同.因为在深度相同后这样后,二者就可以同时向上跳某n层,去识别所到之点是否为…
#include"stdio.h" #include"string.h" #include"iostream" #include"queue" #define M 111111 using namespace std; struct st { int u,v,next,w; }edge[M*2]; int rank[M],head[M],t,pre[M],use[M],dis[M]; void init() { t=0; me…
Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves) 深度优先搜索的解题详细介绍,点击 给你一个有根节点的二叉树,找到它最深的叶节点的最近公共祖先. 回想一下: 叶节点 是二叉树中没有子节点的节点 树的根节点的 深度 为 0,如果某一节点的深度为 d,那它的子节点的深度就是 d+1 如果我们假定 A 是一组节点 S 的 最近公共祖先,<font color="#c7254e&q…
题目描述 给定一棵二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义: “对于有根树T的两个结点u.v,最近公共祖先表示一个结点x,满足x是u.v的祖先且x的深度尽可能大.”(一个节点也可以是它自己的祖先) _______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4 例如,节点5和节点1的最近公共祖先是节点3:节点5和节点4的最近公共祖先是节点5,因为根据定义,一个节点可以是它自己的祖先. 解题思路 考虑用前序遍…
当我们处理树上点与点关系的问题时(例如,最简单的,树上两点的距离),常常需要获知树上两点的最近公共祖先(Lowest Common Ancestor,LCA).如下图所示: 2号点是7号点和9号点的最近公共祖先 我们先来讨论朴素的做法. 首先进行一趟dfs,求出每个点的深度: int dep[MAXN]; bool vis[MAXN]; void dfs(int cur, int fath = 0) { if (vis[cur]) return; vis[cur] = true; dep[cur…
1.前言 最近公共祖先(Least Common Ancestors),简称LCA,是由Tarjan教授(对,又是他)提出的一种在有根树中,找出某两个结点u和v最近的公共祖先问题. 2.什么是最近公共祖先? 在一棵树中,每个结点都有他的父亲和祖先,而最近公共祖先就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点.结合下图和文字应该很好的诠释了最近公共祖先: PS:在LCA中,也可以将结点本身视为自己的祖先 在这颗以结点1为根的树中,4与5的最近…
什么是最近公共祖先? 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点. 所以LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径. 常用来求LCA的算法有:Tarjan/DFS(离线),ST/倍增(在线). 1,Tarjan tarjan的算法复杂度为$O(n+q)$. 思路:每进入一个节点u的深搜,就把整个树的一部分看作以节点u为根节点的小树,再搜索其他的节…