补了一发LCA,表示这东西表面上好像简单,但是细节真挺多。

我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是说f[0][x]是父亲,f[1][x]是爷爷,f[2][x]是高祖父(爷爷的爷爷),f[3][x]是远祖父(高祖父的高祖父)

搞个事:

按古制辈份分为:自己,父亲、祖父、曾祖、高祖、天祖、烈祖、太祖、远祖、鼻祖。

扯回来,这个就是倍增的思想,可以方便的实现O(logn)的LCA,现在让你在构图的时候搞好f数组,一点问题都没有了吧~

然后怎么求LCA?首先,我们先让深度比较深的点往上跳,然后两个一起跳,直到跳到父亲相同。那我们跳的时候,就像二进制一样,可以一次跳2^i次方

caioj1236:(赤裸裸的LCA)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
a[++len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
//f[i][j]表示j的第2^i的祖先
int Bin[],dep[],f[][];
void dfs(int x,int fa)//构树
{
f[][x]=fa;//x的2^0=1就是自己父亲
for(int i=;Bin[i]<=dep[x];i++)f[i][x]=f[i-][f[i-][x]];//倍增,爸爸的爸爸是爷爷
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fa)
{
dep[y]=dep[x]+;
dfs(y,x);
}
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);//让比较深的先往上跳
for(int i=;i>=;i--)//倒着,想象成二进制,比如要找第5个祖先,就变成101,从左往右把所有为一的跳一下
if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
if(x==y)return x;
for(int i=;i>=;i--)//深度一样了,x和y一起跳
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y]){x=f[i][x];y=f[i][y];}
return f[][x];
}
int main()
{
Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
int n,m,x,y;
scanf("%d%d",&n,&m);
len=;memset(last,,sizeof(last));
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
dep[]=;dfs(,);
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}

关于树论【LCA树上倍增算法】的更多相关文章

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

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

  2. LCA的倍增算法

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

  3. LCA树上倍增求法

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

  4. LCA——树上倍增

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

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

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

  6. LCA树上倍增

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

  7. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

    题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...

  8. Lca 之倍增算法

    引入: 比如说要找树上任意两个点的路上的最大值.如果是一般的做法 会 接近o(n)的搜,从一个点搜到另一个点,但是如果询问多了复杂度就很高了. 然后我们会预处理.预处理是o(n²)的,询问是o(1)的 ...

  9. Codeforces 191C (LCA+树上差分算法)

    题面 传送门 题目大意: 给出一棵树,再给出k条树上的简单路径,求每条边被不同的路径覆盖了多少次 分析 解决这个问题的经典做法是树上差分算法 它的思想是把"区间"修改转化为左右端点 ...

随机推荐

  1. 关于shell中常见功能的实现方式总结

    一.shell脚本中连接数据库 二.

  2. ul标签中,li标签的移除、属性值获取

  3. 如何安装python包

    安装python包有两种方法: 使用Python包管理器pip工具 在Linux系统中,首先 yum install python-pip 然后就可以欢快的pip install *** 啦 源代码安 ...

  4. [HNOI2004]宠物收养场(Treap)

    洛谷传送门 这题真是恶心,一开始没理解题意. 原来如果有狗,狗就会存在收养场中,直到有人来领养: 如果有人,人也会存在收养场中,直到有狗来被领养. 就是建一个treap,狗来把狗插进去,人来后把狗领养 ...

  5. CERC 2014 (动态树+主席树)

    CERC 2014 Pork barrel Problem : n个点m条边有边权的无向图,有q个询问,每次询问权值在[L,R]内的边组成的最小生成树的权值和,强制在线. n <= 1000, ...

  6. spring boot 没有主清单属性

  7. poj2767,单向连通图判定,缩点+重新建图+新图DFS

    /*该题被博客里标记为中等题,30分钟内1A,掌握了算法就简单了,单向连通图判定,单向连通图缩点 后必然唯一存在出度为0的点和入度为0的点,并且从入度为0的点出发,可以遍历所有点后到达出度为0点 (一 ...

  8. iOS 如何查看崩溃日志

    参考网址: [转载]https://www.jianshu.com/p/4de55d73c82b [转载]https://blog.csdn.net/qq_26544491/article/detai ...

  9. HDU 2255 二分图最佳匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  10. GOF 23种设计模式目录

    经典的gof 23种设计模式,目录大纲查看. 1. Singleton(单例模式) 保证一个类只有一个实例,并提供访问它的全局访问点. 2. Abstract Factory(抽象工厂模式) 提供一个 ...