LCA + 二分(倍增)
两个最近的点u和v的最近的公共的祖先称为最近公共祖先(LCA)。普通的LCA算法,每算一次LCA的时间复杂度为线性o(n);
这里讲LCA + 二分的方法。首先对于任意的节点v,利用其父节点的信息,可以通过par2[v]=par[par[v]]得到向上走两步的节点。依此信息可以通过par4[v]=par2[par2[v]]得到向上走4步的节点。所以,根据此方法可以得到向上走2^k所得到的节点par[k][v]。每次搜索的复杂度为o(log n),预处理par[k][v]的复杂度为o(nlog n)。(我觉得挑战程序设计LCA部分写的挺明白的)
模版代码如下:
//LCA + 二分 vector <int> G[MAX_V]; //邻接表
int root; //根的编号 int par[MAX_LOG_V][MAX_V]; // 向上走2^k所到的父节点编号(根节点的父节点为-1)
int dep[MAX_V]; //节点的深度 void dfs(int v , int p , int d) { //3个参数分别表示 当前节点 父节点 深度
par[v][] = p;
dep[v] = d;
for(int i = ; i < G[v].size() ; i++) {
dfs(G[v][i] , v , d + );
}
}
//预处理
void init(int n) {
dfs(root , - , ); //预处理出par[0]和dep
for(int k = ; k + < MAX_LOG_V ; k++) {
for(int v = ; v <= n ; v++) {
if(par[k][v] < )
par[k + ][v] = -; //v向上的2 ^ (k + 1)的节点超过根节点
else
par[k + ][v] = par[k][par[k][v]]; //v向上的2^k的节点 又向上的2^k个节点,所以是向上2^(k + 1)个节点
}
}
}
//计算u和v的LCA
int lca(int u , int v) {
if(dep[u] < dep[v]) //让u和v向上走到同一深度
swap(u , v);
for(int k = ; k < MAX_LOG_V ; k++) {
if((dep[v] - dep[u]) >> k & ) { //把深度差化为2进制(快速幂原理) 依次从低位相减
v = par[k][v];
}
}
if(u == v) //要是节点相同则输出LCA
return u;
for(int k = MAX_LOG_V - ; k >= ; k--) { //二分搜索计算LCA
if(par[k][u] != par[k][v]) { //若他们的2^k节点不相同 则u和v向上移动,一直移动直到他们的上一个节点相同
u = par[k][u];
v = par[k][v];
}
}
return par[][u];
}
LCA + 二分(倍增)的更多相关文章
- 关于LCA的倍增解法的笔记
emmmmm近日刚刚学习了LCA的倍增做法,写一篇BLOG来加强一下印象w 首先 何为LCA? LCA“光辉”是印度斯坦航空公司(HAL)为满足印度空军需要研制的单座单发轻型全天候超音速战斗攻击机,主 ...
- LCA的倍增算法
LCA,即树上两点之间的公共祖先,求这样一个公共祖先有很多种方法: 暴力向上:O(n) 每次将深度大的点往上移动,直至二者相遇 树剖:O(logn) 在O(2n)预处理重链之后,每次就将深度大的沿重链 ...
- [模板]LCA的倍增求法解析
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【bzoj2280】[Poi2011]Plot 二分+倍增+二分+最小圆覆盖
题目描述 给出一系列点p_1, p_2, ... , p_n,将其分成不多余m个连续的段,第i段内求一个点q_i,使得q_i到这段内点的距离的最大值的最大值最小 输入 第一行,n m下面n行,每行两个 ...
- noip 2015 运输计划 (lca+二分)
/* 95 最后一个点T了 qian lv ji qiong 了 没学过树剖 听chx听xzc说的神奇的方法 Orz 首先求出每个计划的路径长度 这里写的倍增 然后二分答案 对于每个ans 统计> ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- bzoj2144: 跳跳棋(二分/倍增)
思维好题! 可以发现如果中间的点要跳到两边有两种情况,两边的点要跳到中间最多只有一种情况. 我们用一个节点表示一种状态,那么两边跳到中间的状态就是当前点的父亲,中间的点跳到两边的状态就是这个点的两个儿 ...
- [luoguP2680] 运输计划(lca + 二分 + 差分)
传送门 暴力做法 50 ~ 60 枚举删边,求最大路径长度的最小值. 其中最大路径长度运用到了lca 我们发现,求lca的过程已经不能优化了,那么看看枚举删边的过程能不能优化. 先把边按照权值排序,然 ...
- LCA树上倍增求法
1.LCA LCA就是最近公共祖先(Least common ancestor),x,y的LCA记为z=LCA(x,y),满足z是x,y的公共祖先中深度最大的那一个(即离他们最近的那一个)qwq 2. ...
随机推荐
- poj 3277 City Horizon (线段树 扫描线 矩形面积并)
题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...
- uva 111 - History Grading (dp, LCS)
题目链接 题意:给N,第二行是答案,n个数c1---cn, 代表第一个的顺序是c1,第二个数顺序是c2; 下面每一行是学生的答案,格式同上. 注意:这个给的顺序需要处理一下,不能直接用. 思路:LCS ...
- 【笨嘴拙舌WINDOWS】API
如今,相对于大行其道的对象,服务,API概念的提出要早很多,却依然经久不衰:所谓万变不离其宗,如今很多服务(Web Services,云服务)的提供方式和API如出一辙. Windows API(Ap ...
- ASP.NET MVC 学习1、新增Controller,了解MVC运行机制
1,turorial ,根据链接教程新建一个MVC项目 http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/ ...
- 【多端应用开发系列0.0.0——之总序】xy多端应用开发方案定制
[目录] 0.0.0 [多端应用开发系列之总序]服务器Json数据处理——Json数据概述 0.0.0 [因] 正在学习多客户端应用开发,挖个坑,把所用到的技术方案,用最简单直白的语言描述出来,写成一 ...
- Android开发 |常见的内存泄漏问题及解决办法
在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...
- Android常用组件
UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...
- logback.xml配置
一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文 ...
- java web 学习十二(session)
一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...
- MyBatis的association示例——MyBatis学习笔记之三
前两篇博文介绍的都是单表映射,而实际上很多时候我们需要用到较复杂的映射.今天学会的association的用法,就是一例,现写出来和大家分享(为简洁起见,ant工程中各文件.目录的布局,以及其它与前面 ...