emmmmm近日刚刚学习了LCA的倍增做法,写一篇BLOG来加强一下印象w

  首先 何为LCA?

  LCA“光辉”是印度斯坦航空公司(HAL)为满足印度空军需要研制的单座单发轻型全天候超音速战斗攻击机,主要任务是...

  LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。

  怎么样,很好理解吧!

  然后,关于倍增

  emmmmm,可以这么理解:

  ……

  ……

  ……

  https://blog.csdn.net/jarjingx/article/details/8180560(太烂啦有空再自己填一下这个坑吧x

  怎么样,很好理解吧!

  (懒癌患者是这样的orz,对不住各位观众老爷&&神犇啦

  那么!

  怎么把他们结合在一起就是我们要研究的问题啦。

  相信大家第一次看到形似“给出一棵树和若干结点,求他们的LCA”这种问题就会想到爆搜吧(单次最坏和平均时间复杂度都是O(n))

  但是显而易见,万恶机智的出题人是不会放我们这么简单的做法过哒

  这时候我们就需要在原来的爆搜上加上倍增优化一下时间复杂度(优化之后是O(nlogn))

  我们给这种神秘地操作叫做 树上倍增

  总而言之就是

  用一个二维数组fa[i][j]来表示从第i个结点向上跳 2 ^ j 个结点所在的点,那么理所当然的fa[i][0]表示的就是i点的父结点啦

  

 int lca(int x, int y) {
if (dep[x] > dep[y]) {
swap(x, y); //交换x点和y点,让x点在y点上♂面(噫
}
for (int i = ; i >= ; i--) {
if (dep[y] - ( << i) >= dep[x]) {
y = fa[y][i]; //把y点调整到和x点一个高度
}
}
if(x == y) {
return x; //这里是特判哦,如果调整后x点和y点一样直接返回x就行啦
}
for(int i = ; i >= ; i--) {
if(fa[x][i] == fa[y][i]) {
continue; //如果他们的父亲向上跳2 ^ i个点后是同一个点的话就找到他们的LCA啦
}
else {
x = fa[x][i];
y = fa[y][i]; //要雨♂露♂均♂沾,一起向上跳喏
}
}
return fa[x][]; 返回LCAqwqqq
}

  以上就是倍增LCA的核心算法啦

  然而要知道的是,现在有许多万恶机智的出题人是会卡我们的倍增哒

  所以我们就需要

  优化优化优化!

  因为涉及到图,我们就可以用一种叫派大星链式前向星的东西来优化它(如果你不知道链式前向星可以看看这个

   下面以洛谷的模板题为例,贴一下自己的代码(感谢kkogoro带我“走进LCA”wwww
  

 #include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int Maxv = ; int fa[Maxv * ][], head[Maxv], dep[Maxv];
int cnt, n, m, s; struct edges {
int v, next;
}edge[Maxv * ]; void add(int x, int y){
edge[cnt].v = y;
edge[cnt].next = head[x];
head[x] = cnt++;
} void dfs(int u, int father){
dep[u] = dep[father] + ;
fa[u][] = father;
for (int i = ; ( << i) <= dep[u]; i++) {
fa[u][i] = fa[fa[u][i - ]][i - ];
}
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].v;
if (v != father) {
dfs(v, u);
}
}
} int lca(int x, int y) {
if (dep[x] > dep[y]) {
swap(x, y);
}
for (int i = ; i >= ; i--) {
if (dep[y] - ( << i) >= dep[x]) {
y = fa[y][i];
}
}
if(x == y) {
return x;
}
for(int i = ; i >= ; i--) {
if(fa[x][i] == fa[y][i]) {
continue;
}
else {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][];
} int main(){
int a, b;
memset(head, -, sizeof(head));
scanf("%d %d %d", &n, &m, &s);
for (int i = ; i < n; i++) {
scanf("%d %d", &a, &b);
add(a, b);
add(b, a);
}
dfs(s, );
for(int i = ; i <= m; i++) {
scanf("%d %d", &a, &b);
printf("%d\n", lca(a, b));
}
return ;
}
  怎么样
  很好理解吧www

关于LCA的倍增解法的笔记的更多相关文章

  1. LCA的倍增算法

    LCA,即树上两点之间的公共祖先,求这样一个公共祖先有很多种方法: 暴力向上:O(n) 每次将深度大的点往上移动,直至二者相遇 树剖:O(logn) 在O(2n)预处理重链之后,每次就将深度大的沿重链 ...

  2. [模板]LCA的倍增求法解析

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  3. 【Luogu P3379】LCA问题的倍增解法

    Luogu P3379 题意:对于两个节点,寻找他们的最近公共祖先. 一个显而易见的解法是对于每一个节点我们都往上遍历一遍,记录下它每一个祖先,然后再从另一个节点出发,一步一步往上走,找到以前记录过第 ...

  4. LCA树上倍增

    LCA就是最近公共祖先,比如 节点10和11的LCA就是8,9和3的LCA就是3. 我们这里讲一下用树上倍增来求LCA. 大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点. ...

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

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

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

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

  7. LCA算法倍增算法(洛谷3379模板题)

    倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...

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

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

  9. codeforces 519E A and B and Lecture Rooms(LCA,倍增)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud E. A and B and Lecture Rooms A and B are ...

随机推荐

  1. Appium appium 安装不了

    npm --registry http://registry.cnpmjs.org install -g appium使用npm的国内镜像可以安装,速度很不错.以后不想输入ip的话可以输入以下命令:n ...

  2. The APK failed to install. Error:Could not parse error string.

    问题一: The APK failed to install. Error:Could not parse error string. 今天拖拽自己的apk到模拟器上运行,报上述错误. 搜索解决方案. ...

  3. js 事件event

    var EventUtil = { addHandler: function(element,type,handler){ if(element.addEventListener){ element. ...

  4. sql注入(一)

    SELECT * FROM users WHERE user='uname' AND password='pass' SELECT * FROM users WHERE user='name' AND ...

  5. 【scrapy】其他问题

    今天看<python爬虫开发与项目实践>的17章写代码的时候发现,一个方法的结尾带了红色波浪线: def _process_booklist_item(self,item): ''' 处理 ...

  6. java面试题:Spring

    Spring 面试时,最好能结合底层代码说出IOC,AOP或Spring MVC的流程,能说出拦截器的底层. 如果看过Spring的源码,并能结合设计模式表达,是很大的加分项. IOC Q:讲一下IO ...

  7. 第四章 栈与队列(c5)栈应用:逆波兰表达式

  8. Git 远程仓库 更新url

    git remote -v 查看现有远程仓库的地址url 1. 修改命令git remote set-url origin <URL> 更换远程仓库地址.把<URL>更换为新的 ...

  9. PAT1018 (dijkstra+dfs)

    There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...

  10. mute

    mute - 必应词典 英[mjuːt] n.哑吧:沉默的人:[法律]拒绝答辩的被告人:鸟粪 adj.哑的:缄默无言的:(一时)说不出话的:(猎狗)不叫的 v.排泄:减弱…的声音:柔和…的色调 网络静 ...