倍增法求LCA代码加详细注释
#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代码加详细注释的更多相关文章
- 倍增法求lca(最近公共祖先)
倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...
- 倍增法求LCA
倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...
- HDU 2586 倍增法求lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 倍增法求LCA(最近公共最先)
对于有根树T的两个结点u.v,最近公共祖先x=LCA(u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,根据定义可以看出14和15的最近公共祖先是10, 15和16的最近公共 ...
- 树上倍增法求LCA
我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题 ...
- 在线倍增法求LCA专题
1.cojs 186. [USACO Oct08] 牧场旅行 ★★ 输入文件:pwalk.in 输出文件:pwalk.out 简单对比时间限制:1 s 内存限制:128 MB n个被自 ...
- 倍增法求lca:暗的连锁
https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...
- 浅谈倍增法求解LCA
Luogu P3379 最近公共祖先 原题展现 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \(N,M,S\),分别表示树的结点个数.询问 ...
- 51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释
题目: 看起来比较难,范围10^9 O(n)都过不了,但是仅仅是看起来.(虽然我WA了7次 TLE了3次,被自己蠢哭) 我们观察到 0 <= f[i] <= 6 就简单了,就像小学初中学的 ...
随机推荐
- JMeter基于HTML测试报告的生成
1第一步: 下载ant,搭建ant环境(path的环境变量) 在path中添加ANT_HOME\bin 验证是否搭建成功Lcmd中输入ant 提示这个说明搭建成功. 第二步: 1.jmerer的目录C ...
- sublime text 3 关联鼠标右击
比如有网上有如下方法 https://my.oschina.net/adairs/blog/466777 , 其实一个更简单的方法是运行sublime setup.exe , 直接会有相关提示,下一步 ...
- chrome "items hidden by filters"
今天更新chrome 后遇到console不能显示errors的问题,折腾一番后发现在console的Default levels中选择Default即可.
- vue 细节注意
*只有vm.$data这些被代理的属性是响应的,能够重新渲染视图 *注意,不要在实例属性或者回调函数中(如 vm.$watch('a', newVal => this.myMethod()))使 ...
- wannafly挑战赛4树的距离 离线处理,dfs序
时间限制:C/C++ 2秒,其他语言4秒空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 wyf非常喜欢树.一棵有根数树上有N个节点, ...
- 带你学够浪:Go语言基础系列 - 8分钟学基础语法
对于一般的语言使用者来说 ,20% 的语言特性就能够满足 80% 的使用需求,剩下在使用中掌握. 基于这一理论,Go 基础系列的文章不会刻意追求面面俱到,但该有知识点都会覆盖,目的是带你快跑赶上 Go ...
- Ubuntu 安装 rabbitmq
第一步:安装 erlang 官网:https://www.erlang-solutions.com/resources/download.html 然后在终端输入:erl 显示如下,说明安装成功! E ...
- MyBatis——Mapped Statements collection does not contain value for XXX
报错信息: Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql. ...
- Linux赋权chmod
chmod -R 777 文件名/ 给文件可读.可修改.可执行权限
- redis的安装和简单操作
安装gcc 目地是编译软件 yum install gcc-c++ 1.拷贝并解压 2.编译文件 到解压目录下 执行 make 进行编译依赖项 cd /deps make hiredis lua j ...