#include <iostream>
#include <vector>
#include <algorithm>
#define MAXN 100
//2^MAXLOG2>=最大深度
#define MAXLOG2 7
using namespace std; vector<int>G[MAXN];
int depth[MAXN];
int ancestor[MAXN][MAXLOG2]; void creat()//输入并存储树
{
int n,x,y;
cin>>n;//n条边
for(int i=;i<n;i++)
{
cin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
}
void dfs(int x,int father)
{
depth[x]=depth[father]+;//计算x深度
ancestor[x][]=father;
//计算x结点的2^i步祖先
for(int i=;i<MAXLOG2;i++)
//因为是dfs,所以深度小的结点的ancestor总会先算出来
//MAXLOG2太大了会怎样?因为ancestor[0][i]=0,所以不管怎样往上走都是0
ancestor[x][i]=ancestor[ancestor[x][i-]][i-];
for(int i=;i<G[x].size();i++)
if(G[x][i]!=father)dfs(G[x][i],x);
}
int lca(int x,int y)
{
if(depth[x]<depth[y])swap(x,y);
/*假设x与y深度相差z,x每次走2^i(i从最大每次循环减少1)步总能到达y的深度
证明:将z转换成二进制,再转换成十进制
则肯定等于2^i1 + 2^i2 + 2^i3 ... 形式 */
for(int i=MAXLOG2-;i>=;i--)
//如何防止走多了?走完后的深度比y还小,说明走多了,这时候我们就不走
if(depth[ancestor[x][i]]>=depth[y])x=ancestor[x][i];
if(x==y)return x;
//假设x与LCA相距L步,那么x,y都走L-1步仍然不相等,下面的循环是让x,y走L-1步
for(int i=MAXLOG2-;i>=;i--)
/*如何防止走多了?
注意循环结束条件,并非当x,y走完后相等
如果以x,y相等为结束条件,则有可能会走过了
此循环的目的是为了让x,y走L-1步
LCA相当于x,y的中点
为什么一定刚好走L-1步?
首先能确定的是存在两个结点再往上一步就是LCA
此循环让x,y只要不相等就往上走,x,y肯定会到达这两个结点
即x,y走L-1步会到达那两个结点。自己可以画图试试*/
if(ancestor[x][i]!=ancestor[y][i])
{
x=ancestor[x][i];
y=ancestor[y][i];
}
return ancestor[x][]; //即x再向上走1(2^0)步即是LCA
}
int main()
{
creat();//数据要输入
dfs(,);
//cout<<lca(7,6);
return ;
}

倍增法求LCA代码加详细注释的更多相关文章

  1. 倍增法求lca(最近公共祖先)

    倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...

  2. 倍增法求LCA

    倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...

  3. HDU 2586 倍增法求lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  4. 倍增法求LCA(最近公共最先)

    对于有根树T的两个结点u.v,最近公共祖先x=LCA(u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,根据定义可以看出14和15的最近公共祖先是10,   15和16的最近公共 ...

  5. 树上倍增法求LCA

    我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题 ...

  6. 在线倍增法求LCA专题

    1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自 ...

  7. 倍增法求lca:暗的连锁

    https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...

  8. 浅谈倍增法求解LCA

    Luogu P3379 最近公共祖先 原题展现 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \(N,M,S\),分别表示树的结点个数.询问 ...

  9. 51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释

    题目: 看起来比较难,范围10^9 O(n)都过不了,但是仅仅是看起来.(虽然我WA了7次 TLE了3次,被自己蠢哭) 我们观察到 0 <= f[i] <= 6 就简单了,就像小学初中学的 ...

随机推荐

  1. RocketMQ 入门

    一.rocketMQ是什么 rocketmq是一款低延迟.高可靠.可伸缩.已使用的消息中间件.具有以下特性: 1.支持发布/订阅.点对点(p2p)消息模型 2.同一个队列中支持先进先出(FIFO)和严 ...

  2. 00008 - layui 表单验证,需要验证,但非必输

    当使用layui的验证规则,比如 手机, <input type="text" name="userName" lay-verify="phon ...

  3. 存储系列之 RAID技术原理简介

    引言:RAID技术是现代大规模存储的基础,“基础(技术)是拿来革命的”.我查raid相关资料时,查布尔运算,竟然一路查到“香农原理”,这不是有个视频中HW的任总提到的吗,多基础的东西,任总却毫不含糊, ...

  4. HDU2819

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意: 给出一个N*N的0/1矩阵,只能交换整行或者整列,问最少交换多少次可以变成一个主对角 ...

  5. Robot Framework(4)- 测试套件的基本使用

    如果你还想从头学起Robot Framework,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1770899.html 前言 因为是基于 ...

  6. go语言依赖注入实现

    最近做项目中,生成对象还是使用比较原始的New和简单工厂的方式,使用过程中感觉不太爽快(依赖紧密,有点改动就比较麻烦),还是比较喜欢使用依赖注入的方式. 然后网上没有找到比较好用的依赖注入包,就自己动 ...

  7. PSR-0到PSR-4编程规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

  8. 此flash player与您的地区不相容——更换新版本edge后出现的问题

    最新切换到了edge浏览器,使用flash时提示:"此flash player与您的地区不相容",而chrome是没有问题的.网上找到解决方案,发现一个可以有效解决的方式,如下: ...

  9. Alpha冲刺 —— 5.5

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 Alpha冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.展 ...

  10. Rocket - decode - 最小项与最大项

    https://mp.weixin.qq.com/s/XrBh9Kapj01HdvBi5MkbgA   介绍布尔代数最小项与最大项相关概念,以及Term类的实现.     参考链接: https:// ...