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. 【28.57%】【codeforces 615C】 Running Track

    time limit per test1 second memory limit per test512 megabytes inputstandard input outputstandard ou ...

  2. shp数据和tab数据的两点区别

    作者:朱金灿 来源:http://blog.csdn.net/clever101 shp是ArcGIS的矢量格式,tab是Mapinfo的矢量格式.shp数据和tab数据有两点区别:一是shp数据的f ...

  3. jQuery插件开发小总结

    另一篇 jQuery插件开发通常有3种方式 通过$.extend()来扩展jQuery 通过$.fn 向jQuery添加新的方法 通过$.widget()应用jQuery UI的部件工厂方式创建 通常 ...

  4. C#中的interface没那么简单

    最近在园子里闲逛看到一篇文章“(抽象)类和接口细节分析”,尽管作者很细心很细致.可事实上C#里面的interface没那么简单,interface有着大量不为人知的小秘密的说. 1.值类型也能实现接口 ...

  5. Logical partitioning and virtualization in a heterogeneous architecture

    A method, apparatus, and computer usable program code for logical partitioning and virtualization in ...

  6. linux awk(good)

    一个用awk处理字符串的例子: #!/bin/bash source="nokia201703148855" preffixStr=$(echo $source |awk '{pr ...

  7. SpringBoot、Groovy

    Java——搭建自己的RESTful API服务器(SpringBoot.Groovy)   这又是一篇JavaWeb相关的博客,内容涉及: SpringBoot:微框架,提供快速构建服务的功能 Sp ...

  8. c语言bit倒置最好的算法-离msb-lsb至lsb-msb

    问题 什么是例如最好的算法,下面的转换? 0010 0000 => 0000 0100 从详细的转换MSB->LSB至LSB->MSB, 所有的Bit必须扭转,着.这并非字节顺序的交 ...

  9. PHP中间uniqid在高并发重复问题

    在公用事业最近项目生成token检查问题.首先考虑php中间uniqid()函数生成一个随机字符串,但因为该函数的良好似基于微秒的水平.在高并发的情况下,,也能够产生相同的值. 解1:uniqid(r ...

  10. WPF C#之读取并修改App.config文件

    原文:WPF C#之读取并修改App.config文件 简单介绍App.config App.config文件一般是存放数据库连接字符串的.  下面来简单介绍一下App.config文件的修改和更新. ...