lca即最近公共祖先,求最近公共祖先的方法大概有3种,其实是窝只听说过3种,这3种做法分别是倍增求lca,树剖求lca和tarjan求lca,但是窝只会前2种,所以这里只说前2种算法了。

  首先是倍增求lca,倍增求lca的思想是不断的向上跳,直到跳到lca为止

 

  比如求这棵树中x和y的lca,首先让深度较深的点(x)跳到和深度较浅(y)的点同一个深度,然后先看一下x和y是不是同一个点了,如果是,那么不用再向上跳了,返回x即可。如果不是,需要继续往上跳,而这个往上跳的过程是判断如果跳到的那个深度x和y的祖先不是同一个就可以往上跳,因为如果是同一个的话很有可能跳过了,由于是这样跳的,所以最后x和y跳到的点是兄弟,这时只需要返回他们的父亲就好了。跳的过程相当于是对lca与x,y的深度差二进制分解,只不过不知道这个数是什么罢了。

模板:https://www.luogu.org/problemnew/show/P3379

代码:

 #include<iostream>
#include<cstdio>
using namespace std;
const int maxn=;
int n,m,s;
int x,y;
struct zhw{
int to,last;
}tu[maxn<<];
int head[maxn],tot;
void add(int x,int y)
{
tot++,tu[tot].last=head[x],head[x]=tot,tu[tot].to=y;
}
int fa[maxn][],deep[maxn];
void dfs(int x)
{
for(int i=;i<=;++i)fa[x][i]=fa[fa[x][i-]][i-];
for(int i=head[x];i;i=tu[i].last)
{
if(tu[i].to!=fa[x][])
{
fa[tu[i].to][]=x,deep[tu[i].to]=deep[x]+;
dfs(tu[i].to);
}
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
int t=deep[x]-deep[y];
for(int i=;i>=;i--)
if((<<i)&t)x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
}
return fa[x][];
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<n;++i)
{
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
deep[s]=;dfs(s);
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return ;
}

  树剖那个以后有空了在写QAQ

  

浅谈求lca的更多相关文章

  1. 浅谈倍增LCA

    题目链接:https://www.luogu.org/problemnew/show/P3379 刚学了LCA,写篇blog加强理解. LCA(Least Common Ancestors),即最近公 ...

  2. [算法]浅谈求n范围以内的质数(素数)

    汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...

  3. 【数据结构】浅谈倍增求LCA

    思路 运用树上倍增法可以高效率地求出两点x,y的公共祖先LCA 我们设f[x][k]表示x的2k辈祖先 f[x][0]为x的父节点 因为从x向根节点走2k 可以看成从x走2k-1步 再走2k-1步 所 ...

  4. 浅谈《剑指offer》原题:不使用条件、循环语句求1+2+……+n

    转载自:浅谈<剑指offer>原题:求1+2+--+n 如侵犯您的版权,请联系:windeal12@qq.com <剑指offer>上的一道原题,求1+2+--+n,要求不能使 ...

  5. 浅谈最近公共祖先(LCA)

    LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. (来自百度百科) 一.倍增求LCA 预处理出距点u距离为2^0,2^1,2 ...

  6. 浅谈 LCA

    LCA问题 一.概述: 在图论与计算科学中,两个节点 v 与 w 在有向无环图( directed acyclic graph , DAG )或树中的最近公共祖先(Lowest common ancc ...

  7. js—浅谈方法和思路的重要性(首篇求大佬支持)

    js-浅谈方法和思路的重要性 学了这么久的js,我从老师的,同学的代码中发现,老师写的代码比我们的要清楚的很多,基本上没有太多累赘啊,能少的没有少啊等等..... 废话不多说,下面我们来看看这个我的一 ...

  8. 浅谈LCA

    目录 什么是LCA 倍增求LCA dfs bfs 树剖求LCA 什么是LCA LCA就是最近公共祖先 对于有根树\(Tree\)的两个结点\(u.v\),最近公共祖先\(LCA(T,u,v)\)表示一 ...

  9. 浅谈倍增法求解LCA

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

随机推荐

  1. Android 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

  2. 使用dockerfile构建镜像(docker build)

    Docker buidl .  找出当前文件夹下的Docker build文件名的文件 Docker build -t  centos(镜像名) . 在当前目录下找centos的镜像文件 Docker ...

  3. POJ 4047 Garden

    Garden Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 404 ...

  4. View_01_LayoutInflater的原理、使用方法

    View_01_LayoutInflater的原理.使用方法 本篇博客是郭神博客Android视图状态及重绘流程分析,带你一步步深入了解View(一)的读书笔记的笔记. LayoutInflater简 ...

  5. HDU 1533 Going Home(KM完美匹配)

    HDU 1533 Going Home 题目链接 题意:就是一个H要相应一个m,使得总曼哈顿距离最小 思路:KM完美匹配,因为是要最小.所以边权建负数来处理就可以 代码: #include <c ...

  6. 74LS153 选择器 【数字电路】

    74LS153 我用了八个不同频率的方波信号,用153当作信号选择器,控制环节的开关是4通道的选择器,00 01 10 11分别选择通道 0 1 2 3 以下是八选一的demo

  7. [BZOJ1672][Usaco2005 Dec]Cleaning Shifts 清理牛棚 线段树优化DP

    链接 题意:给你一些区间,每个区间都有一个花费,求覆盖区间 \([S,T]\) 的最小花费 题解 先将区间排序 设 \(f[i]\) 表示决策到第 \(i\) 个区间,覆盖满 \(S\dots R[i ...

  8. stm32与arm7比较(经典)

    http://wenku.baidu.com/link?url=LIVcT1AQL0IgVF1xan5Zy9rXarCBo66hj7OXSxM1ap7FpssO4c3sd1pZd8azfBPr3PBy ...

  9. golang round

    func Round(f float64, n int) float64 {pow10_n := math.Pow10(n)return math.Trunc((f+0.5/pow10_n)*pow1 ...

  10. Vue render: h => h(App) $mount

    $mount()手动挂载 当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中: 假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载.例如: new Vue({ //el: ...