LCA就是最近公共祖先,比如

节点10和11的LCA就是8,9和3的LCA就是3。

我们这里讲一下用树上倍增来求LCA。

大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点。

二树上倍增就是对暴力的优化,改成了一次爬好几步。

具体怎么爬呢?就是两个点每次爬 2^j 步,而 j 满足的是两个点爬到的点不能相同,因为这样可能是公共祖先,但不一定是最近的。在这种条件下要使 j 尽可能的大。

举个例子,比如上图的节点7和8,当 j = 2 时,都爬到了节点 1,然而很显然这不是 LCA(7, 8),所以只能取 j = 1,7和8分别跳到3和4。然后发现3和4跳不了了,算法结束,答案就是3和4的父亲节点2。

还有一个小点,若两个点深度不同,只需让深的点往上跳到相同的深度就行。

接下来就开始写代码了。

先要预处理节点 i 跳 2^j 步跳到的点是什么。开一个数组fa[i][j],代表了节点i向上爬了2^j 步所到达的节点。那么递推式就是 fa[i][j] = fa[fa[i][j - 1]][j - 1]。

然后就直接可以求LCA了。

以洛谷的板子为例。传送门:https://www.luogu.org/problemnew/show/P3379

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 5e5 + ;
vector<int>v[maxn];
int dep[maxn], fa[maxn][],vis[maxn];
void dfs(int now) //预处理
{
vis[now] = ;
for(int i = ; ( << i) <= dep[now]; ++i)
fa[now][i] = fa[fa[now][i - ]][i - ];
for(int i = ; i < v[now].size(); ++i)
if(!vis[v[now][i]])
{
dep[v[now][i]] = dep[now] + ;
fa[v[now][i]][] = now; //就是v[now][i]的父亲now
dfs(v[now][i]);
}
}
int lca(int x, int y) //O(logn)
{
if(dep[x] < dep[y]) swap(x, y);
for(int i = ; i >= ; --i) //使x, y深度相同
if(dep[x] - ( << i) >= dep[y]) x = fa[x][i];
if(x == y) return x; //若两点正好重合,直接返回
for(int i = ; i >= ; --i)
if(fa[x][i] != fa[y][i])
{
x = fa[x][i]; y = fa[y][i];
}
return fa[x][]; //x的父亲节点就是x向上跳2^0步
}
int main()
{
int n, m, s; scanf("%d%d%d", &n, &m, &s);
for(int i = ; i < n; ++i)
{
int a, b; scanf("%d%d", &a, &b);
v[a].push_back(b); v[b].push_back(a);
}
dfs(s);
while(m--)
{
int a, b; scanf("%d%d", &a, &b);
printf("%d\n", lca(a, b));
}
return ;
}

时间复杂度是O(nlogn)。

LCA树上倍增的更多相关文章

  1. Codevs 2370 小机房的树 LCA 树上倍增

    题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...

  2. HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...

  3. 关于树论【LCA树上倍增算法】

    补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是 ...

  4. LCA——树上倍增

    首先,什么是LCA? LCA:最近公共祖先 祖先:从当前点到根节点所经过的点,包括他自己,都是这个点的祖先 A和B的公共祖先:同时是A,B两点的祖先的点 A和B的最近公共祖先:深度最大的A和B的公共祖 ...

  5. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

  6. LCA树上倍增求法

    1.LCA LCA就是最近公共祖先(Least common ancestor),x,y的LCA记为z=LCA(x,y),满足z是x,y的公共祖先中深度最大的那一个(即离他们最近的那一个)qwq 2. ...

  7. NOIP2013 货车运输 (最大生成树+树上倍增LCA)

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

  8. 树上倍增求LCA及例题

    先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...

  9. 两种lca的求法:树上倍增,tarjan

    第一种:树上倍增 f[x,k]表示x的2^k辈祖先,即x向根结点走2^k步达到的结点. 初始条件:f[x][0]=fa[x] 递推式:f[x][k]=f[ f[x][k-1] ][k-1] 一次bfs ...

随机推荐

  1. html2canvas脚本实现将html内容转换canvas内容

    在开始使用html2canvas之前,有一些关于html2canvas及其一些限制的好处. 介绍 该脚本允许您直接在用户浏览器上截取网页或部分网页的“屏幕截图”.屏幕截图基于DOM,因此它可能不是真实 ...

  2. 使用WPF教你一步一步实现连连看(二)

    连连看算法 第一步:我们考虑在同行或者同列的情况: 同行或者同列又分三种情况: 第一:边线,RowNum或者ColNum等于0或者9 第二:两个相邻 第三:同行不相邻,这种事有条件的,所在行(或列)的 ...

  3. 《Photoshop CS4手绘艺术技法》

    书名 <Photoshop CS4手绘艺术技法> 图片 时间 2017-4月  学习 想了想当初的学习动机,自己P图片可是P的是实在是丑就会做几张动图.看完了才发现这行博大精深而且自己的审 ...

  4. 正则检查是否为IP地址

    /// <summary> /// 是否为ip /// </summary> /// <param name="ip"></param&g ...

  5. jQuery基础教程

    1.使用$()函数 $()函数其实是创建了一个jQuery对象. 这个函数接受CSS选择符作为参数,充当一个工厂, 返回包含页面中对应元素的jQuery对象. 所有能在样式表中使用的选择符都可以传给这 ...

  6. Maven之setting.xml配置文件详解

    setting.xml配置文件 maven的配置文件settings.xml存在于两个地方: 1.安装的地方:${M2_HOME}/conf/settings.xml 2.用户的目录:${user.h ...

  7. 性能监控(3)–linux下的iostat命令

    iostat可以显示cpu与磁盘信息,添加-d参数可以只显示磁盘信息

  8. Spark调优_性能调优(一)

    总结一下spark的调优方案--性能调优: 一.调节并行度 1.性能上的调优主要注重一下几点: Excutor的数量 每个Excutor所分配的CPU的数量 每个Excutor所能分配的内存量 Dri ...

  9. 30个极大提高开发效率的Visual Studio Code插件

    译者按: 看完这篇文章,我打算从 Sublime Text 转到 Visual Studio Code 了! 原文: Immensely upgrade your development enviro ...

  10. lfs(systemv版本)学习笔记-第1页

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 一名linux爱好者,记录构建Linux From Scratch的过程 经博客园-骏马金龙前辈介绍,开始接触学习lfs,用博客 ...