大纲

1.树上倍增&欧拉序+RMQ
2.Tarjan
3.例题

1.树上倍&欧拉序+RMQ

定义:给定一棵有根树,若节点u既是节点x的祖先,也是节点y的祖先,则称u是x和y的公共祖先。
在x,y的所有公共祖先中,深度最大的一个称为x,y的最近公共祖先,记为LCA(x, y)。
例如:下图中,2和3的最近公共祖先是1, 2和5的公共祖先是2。4和9的最近公共祖先是2。
两个结点的公共祖先可能有多个(例如2和1都是4,5的公共祖先),但最近公共祖先只有一个。

向上标记:
① 从x向上遍历,直到根节点,遍历过程中标记所有x的祖先。
② 从y向上遍历,遍历过程中首次遇到已标记结点时,该节点就是LCA(x, y);
向上标记法单次询问时间复杂度为:O(N)。
朴素算法:
① DFS/BFS求出树中每个节点的深度。
② 将x和y中深度较大的向上调整,直到x和y的深度相同。
③ 将x和y同时向上调整,直到相遇,首次相遇的结点即是x和y的最近公共祖先。
朴素算法单次询问时间复杂度为:O(N)。
在朴素算法中x和y向上调整时都是一步一步向上调整,倍增法使用倍增的方式向上调整。
在将x和y以倍增的方式向上调整时,如何知道倍增后的祖先是谁?
定义p[i][j]表示节点i的2^j祖先,倍增过程中通过p数组直接获取倍增后的祖先。
如何预处理p[i][j]的值?
i的2 ^ j祖先是i的2 ^ (j-1)祖先的2(j-1)祖先,即:p[i][j] = p[p[i][j-1]][j-1];
可以在dfs/bfs计算结点深度的同时初始化p数组,因为无论是dfs还是bfs都是
从根节点出发,当搜索到节点x时,其所有祖先一定都搜索过了。
预处理p数组时间复杂度为:O(Nlog(N))。
① DFS/BFS求出树中每个节点的深度,并预处理除任意节点的2 ^ j祖先,即: p数组。
② 将x和y中深度较大的以倍增的方式向上调整,直到x和y的深度相同。

if (d[x] < d[y])swap (x , y) ;
for (int j = log2n; j >= 0; j --)if (d[p[x][j]] >= d[y])x = p[x][j] ;

x向上调整的时间复杂度为O(log(N))。
③ 将x和y同时以倍增的方式向上调整,直到x和y相等。
为了防止调整过程中调整到LCA(x,y)的祖先结点,将x和y调整到LAC(x, y)的孩子节点就结束。

if (x == y)return x ;
for (int j = log2n; j >= 0; j --)if (p[x][j] != p[y][j]) {x = p[x][j] ;y = p[y][j] ;}
return p[x][0] ;

2.Tarjan

对于任意节点x和y,它们的最近公共祖先是它们共属的最小子树的根节点。
例如:LCA(4, 7) = 4, LCA(7, 9) = 4,LCA(7, 5) = 2,LCA(7, 10) = 1。
DFS搜索树的过程中会较小的子树会优先搜索完毕,基于这一特点可以离线计算出LCA(x, y)。
所谓离线是在一次搜索过程中把所有询问全部解决,不支持搜索后的动态查询。
Tarjan求下面树中的LCA时,会先搜索子树1中的结点和子树1中的LCA查询。当子树1搜索完
成后,会回退到u,接着搜索子树2。此时如果有两个节点分别属于子树1和子树2,则它们的
公共祖先为u。
当子树1搜索完成,且以u为根的子树还未搜索完成时,所有牵涉到子树1的查询其LCA都是u。
所以当子树1搜索完成后,设置子树1中所有节点和u属于同一集合,并设置u为集合代表。当
计算LCA(x, y),且x属于子树2,y属于子树1时,此时y所在集合的集合代表就是LCA(x, y)。

void tarjan (int x) {p[x] = x ;for (v ∈ son (u)) {tarjan (v) ;union_set (v , x) ;}vis[x] = true ;for (query (x , y)) {if (vis[y]) {lca (x , y) = find (y) ;}}
}

算法过程:
① 将单个查询(x, y)拆分成2个查询(x, y)和(y, x)。(因为不确定x和y谁会先搜索完成)
② 从根节点开始DFS,对于当前搜索到的节点x:
a) 将x的集合代表设置为自己。
b) 枚举x的所有孩子v,递归处理以v为根的子树。
c) 当以v为根子树tarjan完成后将v所在集合合并到x。
d) 当x的所有孩子都tarjan完成后,标记子树x已经搜索完毕。
e) 枚举所有和x相关的搜索查询,对于查询(x, y),如果y也已经搜索完毕,则LCA(x, y) = find(y)。
Tarjan求LCA算法时间复杂度:O(N+M) (M为查询次数),Tarjan不支持在线计算LCA。

【LCA求两点距离】

设dis[i]为根结点到结点i的距离,则:dis(x, y) = dis(x) + dis(y) – 2 * dis(LCA(x, y))。
dis数组可以通过一次dfs/bfs初始化。

3.例题

小科和小丁是从小玩到大的好朋友,高中毕业后他们都考上了全宇宙最牛的大学:科丁大学。科丁大学的校园内有N栋建筑物,编号为1...N,有N-1条双向道路,每条道连接两栋建筑物,任意两栋建筑物之间都有且仅有一条简单路径。小科每天都会从建筑物a出发,前往建筑物b,小丁每天都从建筑物c出发前往建筑物d。小科想知道,他和小丁在前往各自目的地的途中有没有可能在某栋建筑物相遇。
输入格式第1行:两个空格分隔的正整数N和M,N表示建筑物的数量,M表示小科想知道接下来M天他和小丁是否有可能在某栋建筑物相遇。接下来N-1行,每行两个空格分隔的整数u和v,表示有一条道路连接u和v。接下来M行:每行4个空格分隔的整数a, b, c, d,其中第i行的4个整数,表示第i天小科将从a出发前往b,小丁将从c出发前往d。
输出格式输出M行:其中第i行表示第i天小科和小丁是否有可能相遇,如果有可能输出"YES",否则输出“NO”。
输入输出样列
输入样例1:5 3
1 2
2 3
1 4
4 5
1 2 3 4
2 5 3 4
2 3 4 5输出样例1:YES
YES
NO说明【数据范围】1<=N, M <= 100000;1 <= u, v, a, b, c, d <= N。

【c++提高1】最近共先祖LCA优化求法相关推荐

  1. 模板 - LCA最近公共祖先(倍增法、Tarjan、树上差分、LCA优化的次小生成树)

    整理的算法模板合集: ACM模板 注意x和y的LCA可以是x或者y本身 一.LCA的在线倍增算法 /*给定一棵包含 n个节点的有根无向树,有 m个询问,每个询问 给出了一对节点的编号 x和 y,询问 ...

  2. ckks方案优化最好的_站群如何优化才能提高SEO效果?站群优化方案有哪些?

    在竞争激烈的市场环境中,很多企业为了能够"崭露头角",总是想尽方法让自己的网站处在较前的位置,获得更多曝光的机会.然而,互联网的竞争大,能取胜的手段也是各式各样的,如站群优化是大多 ...

  3. 如何提高CAD设计效率?CAD软件优化技能加载中…

    对于设计师来说,加班仿佛已经成为了生活的常态.要想实现高效办公,减少加班就需要在电脑配置有限的情况下,通过一些自定义设置,让CAD设计更加丝滑.高效.下面小编给大家分享一下如何深度优化CAD软件,给C ...

  4. JVM性能优化(四)提高网站访问性能之Tomcat优化

    一.前言 tomcat 服务器在JavaEE项目中使用率非常高,所以在生产环境对tomcat的优化也变得非常重要了,对于tomcat的优化,主要是从2个方面入手,一是tomcat本身的配置,另一个是t ...

  5. JVM性能优化(四)提高网站访问性能之Tomcat优化,晒出收入

    vim tomcat-users.xml 需要配置文件,配置tomcat的管理用户 写入以下内容: 保存退出 如果是tomcat7,配置了tomcat用户就可以登录系统了,但是tomcat8中不行,还 ...

  6. JVM 性能优化(四)提高网站访问性能之 Tomcat 优化,java 程序开发实用教程邱加永答案

    启动 tomcat 2.33 启动访问 成功访问 tomcat 地址后,点击 首页中Server Status,输入用户名密码tomcat/tomcat 进入页面,我们需要关注的就是其中 JVM 的列 ...

  7. 解题报告:luogu P4180 [BJWC2010]严格次小生成树(次小生成树、倍增LCA优化、O(mlogn) )

    P4180 [BJWC2010]严格次小生成树 次小生成树有两种,一种是不严格次小生成树,也就是可以数值上等于最小生成树,一种是严格次小生成树,是权值严格大于最小生成树,两种求法大同小异. 方法2在严 ...

  8. 结合计算机专业怎么提高工匠精神,以“工匠精神”优化技工院校计算机教学

    以"工匠精神"优化技工院校计算机教学 刘洪 江苏省盐城技师学院 224002 摘要:进入本世纪以来,职业教育快速发展,规模不断扩大.在这一过程中,技工院校激烈的生源竞争并没有导致其 ...

  9. 提高pyautogui识图率的优化方案

    -opencv-python的模板匹配算法Template Matching ​ (一)需求分析 ​ 如今2021年,祖国发展进入了新征程,科技技术的发展,更是不可同日而语,自动化人工智能越来越普及, ...

最新文章

  1. java core日志在哪里_java-如何在未启用日志记录功能的情况下在...
  2. SQLServer-sysobjects-type
  3. 微服务实战(四):服务发现的可行方案以及实践案例
  4. css设置input框长度_干货极致分享浅谈CSS属性,有趣的盒模型。网友:哎呦不错哦!...
  5. C语言最重要的知识点(电子文档)
  6. 学习随笔:Django 补充及常见Web攻击 和 ueditor
  7. python使用大漠插件进行脚本开发的尝试(一)
  8. matlab 判断元素索引_MATLAB图像处理:08:在交通视频中检测汽车
  9. python FIFO命名管道
  10. java什么是reference_理解java reference
  11. 看我!挖到了一个3万美元的 Instagram 漏洞
  12. xshell linux查看cpu,Linux系统CPU子系统,命令和监控
  13. 基于 HPSocket , 实现 socket 通讯
  14. 基于华为云ModelArts(实现垃圾分类识别)
  15. 设置和取消Word文档打开密码的三种方法
  16. 资格考试_第二章_证券投资基金概述
  17. 代码随想录第二天 leetcode 977、209、59
  18. ajax注解解决中文乱码,基于注解的简单MVC框架的实现,以及jquery,prototype,ajax传输乱码问题的一点解决方法...
  19. mysql rls_各种类型RLS自适应滤波算法的C++实现
  20. 鲁大师2022牛角尖颁奖盛典落幕,年度最强产品揭晓!

热门文章

  1. Unity3d:一个简单的画圈圈手势判断
  2. Data Catalog3.0:Modern Metadata for the Modern Data Stack
  3. HTML讲解(HTML结构及标签)
  4. 一个window下的简单的全局快捷键向指定的进程发送的c代码与exe程序下载(二)
  5. Cloning A Database Home And Changing The User/Group That Owns It
  6. 面向对象编程 面向过程编程_面向对象的编程真的是死定了
  7. 武汉理工大学2019计算机考研专业课题目(回忆版)
  8. 【Shopee干货】虾皮广告关键词选词技巧
  9. “四舍六入五成双规则” 与 C语言如何实现“四舍五入”
  10. 10.30系统进程及服务控制,前后台调用,kill,进程信号,top进程动态监控,系统控制systemctl,ssh服务和认证,用户登陆审计