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. Quartz 在线Cron表达式

    Quartz自己配置Cron好麻烦,下面是一个在线Cron表达式生成器的网站,非常方便,现在使用Cron时基本上就直接用这个了. http://cron.qqe2.com/ Cron表达式 cronE ...

  2. session_start()的逻辑

    //session_start -Start new or resume existing session session_start(); print_r($_SESSION); //看有没有ses ...

  3. Method for browsing internet of things and apparatus using the same

    A method for browsing Internet of things (IoT) and an apparatus using the same are provided. In the ...

  4. Windows DPI Awareness for WPF

    原文 Windows DPI Awareness for WPF 对于 WPF 程序,要控制程序的 DPI 感知程度,可在 App.manifest 中添加如下代码. 本文知识已经陈旧,你可以阅读这两 ...

  5. 将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小)

    原文:将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小) WPF的XAML文档(Main.xaml): <Window x:Class="SVG2Image.Ma ...

  6. Leetcode 328 Contains Duplicate set和map应用

    找出数组中重复的数,裸的map和set题 class Solution { public: bool containsDuplicate(vector<int>& nums) { ...

  7. Matlab Tricks(二十五) —— 二维图像的 shuffle

    比如对于 mnist (手写字符图像),每幅图像的像素点为 28*28,所以有: perm = randperm(28*28); % 重排列 mnist.train_images = reshape( ...

  8. TL9000 电信业质量体系管理标准

    1.背景介绍:1987年国际标准化组织创立了ISO9000标准.标准发布后,在世界范围内得到了迅速的推广和广泛的认可,成为全世界衡量质量管理水平与质量保证能力的公共标准.九十年代,美国三大汽车公司和航 ...

  9. Android Studio怎样提示函数使用方法

    Eclipse有一个非常好的功能,就是当你代码调用某个android API时,鼠标移到相应的函数或者方法上,就会自己主动有一个悬 浮窗提示该函数的说明(所包括的參数含义,该方法功能).迁移到Andr ...

  10. Bootstrap Button 使用方法

    Getting Started <!-- basic button --> <com.beardedhen.androidbootstrap.BootstrapButton andr ...