LCA的多种求法(超详细!!!)
倍增求LCA
(1)树上倍增法 预处理
设f[x,k]表示x的2^k辈祖先,即从x向根节点走2^k步到达的节点。特别地,若该节点不存在,则令f[x,k]=0。f[x,0]就是x的父节点。可以得出f[x][k]=f[f[x][k-1]][k-1]。
我们可以对树进行遍历,由此得到f[x,0],再计算f数组所有值。
以上部分是预处理,时间复杂度为O(nlogn)。之后可以多次对不同的x,y计算LCA,每次询问的时间复杂度为O(logn)。
【代码实现】 预处理
void dfs(int u,int father)
{
Dep[u]=Dep[father]+;
for(int i=;i<=;i++)
{
if(!f[u][i)break;
else f[u][i+]=f[f[u][i]][i];
}
for(int e=first[u],v; v=go[e],e; e=next[e])
{
if(v==father) continue;
f[v][]=u; //v向上跳2^0=1就是u
dfs(v,u);
}
}
(2)基于f数组计算LCA(x,y)
分为以下几步:
1.设dep[x]表示x的深度。不妨设dep[x]≥dep[y](否则可交换x,y)。
2.用二进制拆分思想,把x向上调整到与y同一深度。具体来说,就是依次尝试从x向上走k= 2logn,…,21,20步,若到达的节点比y深,则令x=f[x,k]。
3.若此时x=y,说明已经找到了LCA,LCA就等于y。
4.若此时x≠y,依次尝试把x,y同时向上走 k= 2logn,…,21,20步,若f[x,k]≠f[y,k](即仍未相会),则令x=f[x,k],y=f[y,k]。
5.此时x,y必定只差一步就相会了,它们的父节点f[x,0]就是LCA。
【代码实现】 查询x,y的LCA
int LCA(int x,int y)
{
if(Dep[x]<Dep[y]) swap(x,y); //让x深度较大
for(int i=;i>=;i--) //先将x,y跳到一个深度,一定要倒着for
if(Dep[f[x][i]]>=Dep[y]) x=f[x][i]; //先跳到同一层
if(x==y) return x; //如果相等直接返回
for(int i=;i>=;i--) //此时x,y已跳到同一层
if(f[x][i]!=f[y][i]) //如果f[x][i]和f[y][i]不同才跳
x=f[x][i],y=f[y][i];
return f[x][]; //x,y是深度最浅且不同的点,即lca的子结点
}
树链剖分求LCA
将静态树上的点按某种方式组织起来,剖分成为若干条链,形成若干个序列,则操作路径就会被拆分为几条链,也就是若干个完整序列
轻重边剖分: 我们将树中的边分成重边和轻边。如下图,加粗的边是重边,其余是轻边。 我们可以以任意点为根,然后记size[u]为以u为根的子树的结点个数,令 为v所有儿子中size值最大的一个儿子,则(u,v)为重边,v称为u的重儿子。 到其余儿子的边为轻边。
轻重边剖分的过程可以使用两次dfs来实现。
剖分过程中要计算如下5个值:
f[x]:x在树中的父亲
size[x]:x的子树结点数(子树大小)
dep[x]:x在树中的深度
son[x]:x的重儿子,即为重边
top[x]:x所在重路径的顶部结点(深度最小)
第一遍dfs计算前4个值, 第二遍dfs计算后1个值。
查询LCA:
1、找到x、y所在的链头
2、如果两个链头不相等,则选择链头深度大的往上跳
3、最后两个链头相等,说明在同一条重路径上,深度浅的就是LCA
看到这里勤奋好学的你一定已经摩拳擦掌、跃跃欲试了吧
那么我们来做一道简单的模板题
【例 1】点的距离
【题目描述】
给定一棵 n 个点的树,Q 个询问,每次询问点 x 到点 y两点之间的距离。
【输入】
第一行一个正整数 n,表示这棵树有 n 个节点; 接下来 n−1 行,每行两个整数 x,y表示 x,y 之间有一条连边; 然后一个整数 Q,表示有 Q个询问; 接下来 Q行每行两个整数 x,y 表示询问 x 到 y 的距离。
【输出】
输出 Q 行,每行表示每个询问的答案。
【输入样例】
6 1 2 1 3 2 4 2 5 3 6 2 2 6 5 6
【输出样例】
3 4
---(QAQ格式的问题我真的搞不nai)
解法一:倍增
解法二:树链剖分
如果还想进一步了解运用LCA,亲亲,这边建议您可以去AC这两道题题哦~
这是一个传送门...传送门2(才不是没有灵魂的可爱传送门呢QWQ)
蟹蟹资瓷,请顺手点个“推荐”吧~mua(づ ̄3 ̄)づ╭❤~
(2019/8/17更:还想再bb一句,传送门什么的太累了不想做了,还是去首页找找吧,在标签里看“LCA”或者“树上倍增法”应该会有你想要的
LCA的多种求法(超详细!!!)的更多相关文章
- 超详细的Xcode代码格式化教程,可自定义样式。
超详细的Xcode代码格式化教程,可自定义样式. 为什么要格式化代码 当团队内有多人开发的时候,每个人写的代码格式都有自己的喜好,也可能会忙着写代码而忽略了格式的问题.在之前,我们可能会写完代码后,再 ...
- 超全超详细的HTTP状态码大全(推荐抓包工具HTTP Analyzer V6.5.3)
超全超详细的HTTP状态码大全 本部分余下的内容会详细地介绍 HTTP 1.1中的状态码.这些状态码被分为五大类: 100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. ...
- c++ 网络编程课设入门超详细教程 ---目录
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9663167.html c++ 网络编程(一)TCP/UDP windows/linux 下入门 ...
- java 多线程超详细总结——阿里大牛熬夜整理
引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个 ...
- c++ 网络编程(九)LINUX/windows-IOCP模型 多线程超详细教程及多线程实现服务端
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html 先讲Linux下(windows下在后面可以直接跳到后面看): 一.线程 ...
- Java中的三大特性 - 超详细篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的三大特性 - 超详细篇>,希望对大家有帮助,谢谢 这一节的内容可能有点多,大家可以选择性的来看 简介 Java的三大特性:封装.继 ...
- 超详细的node/v8/js垃圾回收机制
前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...
- JavaWeb和WebGIS学习笔记(七)——MapGuide Open Source安装、配置以及MapGuide Maestro发布地图——超详细!目前最保姆级的MapGuide上手指南!
JavaWeb和WebGIS学习笔记(七)--MapGuide Open Source安装.配置以及MapGuide Maestro发布地图 超详细!目前最保姆级的MapGuide上手指南! 系列链接 ...
- 【转】(超详细)jsp与servlet之间页面跳转及参数传递实例
初步学习JavaEE,对其中jsp与Servlet之间的传值没弄清楚,查看网上资料,发现一篇超详细的文章,收获大大,特此记录下来.具体链接:http://blog.csdn.net/ssy_shand ...
随机推荐
- .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml)
.net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml) 首先设置 Startup.cs 文件 配置 ConfigureServices services .Add ...
- N(C)O(S)I(P)P 2019 退役记
N(C)O(S)I(P)P 2019 退役记 day-4 今天下午老师突然咕了,于是一下午欢乐时光 今天上午考试T3线段树维护个区间加,区间乘 一遍过编译,一遍过样例(第一次,俺比较弱(虽然也发现和暴 ...
- Java自学-日期 日期格式化
Java中使用SimpleDateFormat 进行日期格式化类 SimpleDateFormat 日期格式化类 示例 1 : 日期转字符串 y 代表年 M 代表月 d 代表日 H 代表24进制的小时 ...
- Beego 学习比较8:SQL语句
SQL语句 1> 常用的SQL语句 1->新增 insert into 表名(字段A,字段B,…) Values(字段A值,字段B值,…) 2->更新 update 表名 ...
- Java 面向对象(八) 权限修饰符 和 final、native 关键字
一.权限修饰符 1.概述 在 Java 中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限: public:公共的: protected:受保护的: default: ...
- 英语gzibeads天珠gzibeads单词
天珠英语是gZiBeads,藏语叫(si , 斯)汉语译为“斯”或“瑟”,又称“天降石”.在<藏汉大辞典>里天珠的解释为:“亚玛瑙,猫睛石,一种宝石,俗称九眼珠.入药能治脑溢血”.最早的天 ...
- 2 Android程序的执行
Android系统采用的是分层架构,分四层: 1. Applicitations:应用层 2. Applicitation Framework:架构层 3. Libraries:类库层 4. ...
- 生成小程序菊花码(生成菊花码、更换中间logo、更改图片尺寸,加文字)
<?php /** * 获取小程序二维码 */ class getMiniQrcode { public $db = ''; public function __construct() { $t ...
- Docker09-实战-快速搭建wordpress
目录 wordpress介绍 传统方式搭建wordpress运行环境的弊端 使用Docker快速构建wordpress wordpress介绍 wordpress是使用PHP语言开发的博客平台,用户可 ...
- List加载因子和扩容因子
List.Map.set的加载因子,默认初始容量和扩容增量 首先,这三个概念说下.初始大小,就是创建时可容纳的默认元素个数:加载因子,表示某个阀值,用0~1之间的小数来表示,当已有元素占比达到这个阀值 ...