#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. 华为Mate8手机优化技巧

    我的华为Mate8手机手机存储(手机内存)32G, 运行内存3G,2016年买的手机,两样数值都偏小,导致使用手机的时候经常卡顿,一天来回清理垃圾.清理内存很多次,要运行微信.QQ等占用运行内存较多的 ...

  2. VIOS挂载ISO文件

    6.VIOS挂载ISO文件 1.给vhost建立虚拟设备 mkvdev -vadapter vhostX -fbo -dev cdx 2.建立存放ISO的资料库 mkrep -sp rootvg -s ...

  3. java判断是否是合法IP

    public boolean ipCheck(String text) { if (text != null && !text.isEmpty()) { // 定义正则表达式 Stri ...

  4. oracle 查询表及字段结构

    select --*tcl.column_name,cc.comments col_comments,data_type,case data_type when 'NUMBER' then '('|| ...

  5. Netty框架问题记录1--多线程下批量发送消息导致消息被覆盖

    业务背景 项目是基于Netty实现的实时课堂项目,课堂中老师需要对试卷进行讲解,则老师向服务器发送一个打开试卷信息的请求,服务器获取试卷信息,将试卷信息发送给所有的客户端(学生和老师). 发送给学生的 ...

  6. PAT 乙级-1025 链表反转

    给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转.例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4:如果K为4,则输出应该为4→3→2→1→5→6,即最后 ...

  7. BZOJ1059 二分匹配

    1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4810  Solved: 2297[Submit][Stat ...

  8. CF55D

    题目大意: 定义:beautiful number,一种能整除它的所有非 0 数位的数字. 给你 l 和 r,请求出 [l,r] 中 beautiful number 的个数. 解题思路: 数位 DP ...

  9. vue-cli 如何修改或删除预设preset记录

    preset其实是你在create新vue项目的时候,生成的插件配置项预设,也就是你在项目中需要用到的插件安装成功了之后,会生成一个关于preset的文件,当你再次create新的vue项目的时候,就 ...

  10. Poj2586 每五个月都是亏

    题目大意: MS公司(我猜是微软)遇到了千年虫的问题,导致数据大量数据丢失.比如财务报表.现在知道这个奇特的公司每个月不是盈利就是亏损(废话),而且无论是盈利和亏损都有一个定值(亏少了它还不干).经过 ...