lca问题是最近公共祖先问题,一般是针对树结构的。
现在有两种方法来解决这样的问题

1. On-line algorithm

用比较长的时间做预处理。然后对每次询问进行回答。

思路:对于一棵树中的两个节点,假设是u和v。我们要找到他们的最近的一个祖先,那么我们可以这样找,首先判断他们是不是一辈儿的人,也就是说他们的深度是不是一样的,如果一个较深(u),一个较浅(v)。我们可以不断的找较深的节点的祖先,直到u和v的深度一致。如果此时u和v重合了,那么u(v)就是他们的最近公共最先,如果不重合,这时,就可以同时找u和v的祖先,直到找到为止(最坏的情况是根节点)。

这个思路比较好理解,处理也很方便,在求lca之前,可以通过dfs找到所有节点的father信息和depth信息。然后就可以按照思路进行求解了。

这个问题和编程之美中的一个题目非常的类似:判断两个链表是否相交。

扩展问题是,找他们的第一个交点(假设他们相交的话)。

思路:首先能够找到两条链表的长度,这个其实是两个链表首指针的depth信息。然后判断他们的depth是否一样,如果一个深,一个浅,那么首先让他们depth相同(对于指针,只需要next就可以了),然后判断当前的两个指针是否重合,如果不重合,那么两个指针,一起next,直到找到第一个交点。

发现,这两问题惊人的相似。感叹算法的灵活性~

2. off-line algorithm

离线算法,就是把所有的询问都读取进来,在算法执行的过程中,就把所有的询问回答了。

tarjan 算法是经典的离线lca算法。

tarjan算法利用了一个用于集合操作的数据结构-并查集(union-find set or disjoint set). 不过这里这个数据结构只是辅助性的,对于理解算法并无影响,理解了算法可以在去了解并查集是怎么一回事。

tarjan算法基于这样一个规律:假设当前节点为root,root节点肯定有很多子树了(每个儿子带领一个),那么我们从最左边的子树开始研究,如果要查询的两个节点u,v都在最左子树,那么这变成了一个更小规模的问题了。如果u在最左子树,而v在其他的子树,那么lca(v,u)=father(u)了。那么如果u在最左子树的一个子树里边,那么lca(v,u) = father(father(u)). 看到这里,熟悉并查集的同学,可能就知道了这就有点象查找集合的father信息。没错,这就是tarjan算法核心思想。

再用简单的语言描述一下:当我们dfs完一个节点v的时候,可以想象,以v为根的所有节点的father全是v了,此时我们从询问中查找,有没有和v相关的询问。如果有,那么查看u是否已经访问过了,如果访问过,肯定有father信息。试想,如果u和v在一棵子树里,那么v和u的lca就是v了。如果u在之前的子树里,lca(v,u) = father(u) 或者 lca(v,u)=father(father(u)),总之就是找u所在集合的根元素了。此时此刻,基本就把算法的思想搞的很明白了。

最近公共祖先(least common ancestors algorithm)的更多相关文章

  1. 最近公共祖先 Lowest Common Ancestors

    基于深度的LCA算法:  对于两个结点u.v,它们的深度分别为depth(u).depth(v),对于其公共祖先w,深度为depth(w),u需要向上回溯depth(u)-depth(w)步,v需要d ...

  2. 最近公共祖先 Least Common Ancestors(LCA)算法 --- 与RMQ问题的转换

    [简介] LCA(T,u,v):在有根树T中,询问一个距离根最远的结点x,使得x同时为结点u.v的祖先. RMQ(A,i,j):对于线性序列A中,询问区间[i,j]上的最值.见我的博客---RMQ - ...

  3. [Swift]LeetCode235. 二叉搜索树的最近公共祖先 | Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  4. [Swift]LeetCode236. 二叉树的最近公共祖先 | Lowest Common Ancestor of a Binary Tree

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  5. 最近公共祖先 · Lowest Common Ancestor

    [抄题]: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. “Th ...

  6. 学习笔记--最近公共祖先(LCA)的几种求法

    前言: 给定一个有根树,若节点\(z\)是两节点\(x,y\)所有公共祖先深度最大的那一个,则称\(z\)是\(x,y\)的最近公共祖先(\(Least Common Ancestors\)),简称\ ...

  7. 最近公共祖先 LCA 倍增算法

          树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...

  8. [总结]最近公共祖先(倍增求LCA)

    目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一 ...

  9. 编程算法 - 二叉树的最低公共祖先 代码(C)

    二叉树的最低公共祖先 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉树的最低公共祖先(lowest common ancestor), 首先先序遍 ...

随机推荐

  1. 深度剖析:最新云端开发工具如何实现敏捷+DevOps开发落地

    相信很多软件开发人员们对今年国内新兴的云端开发工具——华为软件开发云都有耳闻,有些人可能还免费体验过,由于它5人以下的团队是免费使用的,很庆幸本人的这个项目正好5个人,就注册使用了.下面就自己的使用心 ...

  2. linux tesseract识别名片

    用tesseract识别名片,无任何训练 数字,字母识别的准确率比较高,没有错误,规范的汉字识别的还可以,比如名片背面,正面的就错误比较多了: 没有任何训练,识别的还算可以了:我们主要要的电话和QQ ...

  3. vue axios拦截器加全局loading

    import axios from 'axios' import util from './util' import {showFullScreenLoading, tryHideFullScreen ...

  4. 【Python注意事项】如何理解python中间generator functions和yield表情

    本篇记录自己的笔记Python的generator functions和yield理解表达式. 1. Generator Functions Python支持的generator functions语 ...

  5. 简明Python3教程(A Byte of Python 3)

    关键字:[A Byte of Python v1.92(for Python 3.0)] [A Byte of Python3] 简明Python教程 Python教程 简明Python3教程  简明 ...

  6. CSRF 专题

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造.      也被称为:one click attack/session riding(一 ...

  7. Boltzmann 玻尔兹曼机(BM)

    Hopfield + 模拟退火 ⇒ Boltimann machine(随机神经网络),由 Hinton 和他的长期合作者 Sejnowski(Hopfield 的博士生) 共同提出. 1. 基本公式 ...

  8. c语言指针详细解释

    指针是C语言中广泛使用的一种数据类型. 运用指针编程是C语言最基本的风格之中的一个.利用指针变量能够表示各种数据结构: 能非常方便地使用数组和字符串: 并能象汇编语言一样处理内存地址,从而编出精练而高 ...

  9. RDIFramework.NET框架SOA解(集Windows服务、WinForm形式和IIS发布形式)-分布式应用程序

    RDIFramework.NET框架SOA解决方式(集Windows服务.WinForm形式与IIS形式公布)-分布式应用 RDIFramework.NET,基于.NET的高速信息化系统开发.整合框架 ...

  10. WPF DataGrid 触发器

    <DataGrid.RowHeaderStyle> <Style TargetType="DataGridRowHeader"> <Style.Tri ...