浅谈求lca
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的更多相关文章
- 浅谈倍增LCA
题目链接:https://www.luogu.org/problemnew/show/P3379 刚学了LCA,写篇blog加强理解. LCA(Least Common Ancestors),即最近公 ...
- [算法]浅谈求n范围以内的质数(素数)
汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...
- 【数据结构】浅谈倍增求LCA
思路 运用树上倍增法可以高效率地求出两点x,y的公共祖先LCA 我们设f[x][k]表示x的2k辈祖先 f[x][0]为x的父节点 因为从x向根节点走2k 可以看成从x走2k-1步 再走2k-1步 所 ...
- 浅谈《剑指offer》原题:不使用条件、循环语句求1+2+……+n
转载自:浅谈<剑指offer>原题:求1+2+--+n 如侵犯您的版权,请联系:windeal12@qq.com <剑指offer>上的一道原题,求1+2+--+n,要求不能使 ...
- 浅谈最近公共祖先(LCA)
LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. (来自百度百科) 一.倍增求LCA 预处理出距点u距离为2^0,2^1,2 ...
- 浅谈 LCA
LCA问题 一.概述: 在图论与计算科学中,两个节点 v 与 w 在有向无环图( directed acyclic graph , DAG )或树中的最近公共祖先(Lowest common ancc ...
- js—浅谈方法和思路的重要性(首篇求大佬支持)
js-浅谈方法和思路的重要性 学了这么久的js,我从老师的,同学的代码中发现,老师写的代码比我们的要清楚的很多,基本上没有太多累赘啊,能少的没有少啊等等..... 废话不多说,下面我们来看看这个我的一 ...
- 浅谈LCA
目录 什么是LCA 倍增求LCA dfs bfs 树剖求LCA 什么是LCA LCA就是最近公共祖先 对于有根树\(Tree\)的两个结点\(u.v\),最近公共祖先\(LCA(T,u,v)\)表示一 ...
- 浅谈倍增法求解LCA
Luogu P3379 最近公共祖先 原题展现 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \(N,M,S\),分别表示树的结点个数.询问 ...
随机推荐
- CentOS 开启 IPV6
编辑网卡地址:#vi /etc/sysconfig/network-scripts/ifcfg-eth0IPV6INIT=yesIPV6FORWARDING=yesIPV6ADDR=2607:9000 ...
- jquery的ajax总结
jquery的ajax总结 一.总结 一句话总结:ajax函数中层级关系如下: 最底层的封装方式: $.ajax(); 第二层: .load(),$.get(), $.post() 最高层: $.ge ...
- 今日SGU 5.8
SGU 109 题意:一个n*n的矩形,起点在1,1然后每次给你一个操作,走ki步,然后你可以删除任意一个点这次步走不到的,删了就不能再走了,然后问构造这种操作,使得最后删除n*n-1个点 剩下一个点 ...
- zookeeper提供了什么
简单的说,zookeeper=文件系统+通知机制. 每个子目录项如 NameService 都被称作为 znode,和文件系统一样,我们能够自由的增加.删除znode,在一个znode下增加.删除子z ...
- onvif开发实战2--总结框架搭建
完成框架搭建后,编写自己的主函数起onvif服务 编写makefile objs = onvif.o onvif_func.o duration.o soapC.o soapServer.o stds ...
- 嵌入式 Linux应用程序如何读取(修改)芯片寄存器的值
这一问题来自项目中一个实际的需求:我需要在Linux启动之后,确认我指定的芯片寄存器是否与我在uboot的配置一致. 举个例子:寄存器地址:0x20000010负责对DDR2的时序配置,该寄存器是在u ...
- Catch Me If You ... Can't Do Otherwise--转载
原文地址:https://dzone.com/articles/catch-me-if-you-cant-do-otherwise I don't know whether it's an anti- ...
- Linux系统捕获数据包流程
Linux系统捕获数据包流程 为了提高数据包的捕获效率,瓶颈问题是一个需要非常关注的焦点.减少在捕获数据包过程中的瓶颈,就能够提高数据包捕获的整体性能.下面本文将以Linux操作系统为平台,分析捕获数 ...
- Navicat for MySQL 新建查询时,报can't create file ...系统找不到指定的文件夹出现问题
如图点击新建查询报错 解决办法 将这个路径修改一下就ok了
- sql 高性能存储过程分页
USE [Lyjjr] GO /****** Object: StoredProcedure [dbo].[P_ViewPage] Script Date: 05/29/2015 17:18:56 * ...