LCA--P3379 【模板】最近公共祖先(LCA)
*倍增LCA:
设$f[u][k]$表示u的$2^k$辈祖先,即从$u$向根节点走$2^k$步到达的节点,特别的,若该节点不存在,则$f[u][k]$=0.$f[u][0]$就是$x$的父亲节点。因为$u$向根节点$2^k$$\rightarrow$向根节点走$2^{k-1}$,再走$2^{k-1}$步。所以对于 k∈ [1,logn] ,有$f[u][k]=f[f[u][k-1]]]k-1]$。$f$数组利用了递推的思想。递推式为$f[u][k]=f[f[u][k-1]][k-1]$。因此,我们可以对树进行DFS
inline void Deal_first(int u,int fa)
{
dep[u]=dep[fa]+;
for(int i=;i<;i++)
f[u][i+]=f[f[u][i]][i];
for(int i=head[u];i;i=t[i].nex)
{
int v=t[i].to;
if(v==fa) continue;
f[v][]=u;
Deal_first(v,u);
}
return;
}
①设$dep[x]$表示$x$的深度。那么设$dep[x]\ge dep[y]$。(否则可交换$x,y$)
②利用二进制拆分的思想,把$x$向上调整到与$y$同一深度。即:依次尝试从$x$向上走$k$=$2^{logn}……2^1 ,2^0$步,若到达的点比$y$深,则令$x=f[x][k]$
③若此时$x=y$,则说明已经找到了$LCA$,两点的$LCA$就等于$y$。
④若此时的 $x$ ≠ $y$ ,那么 $x$,$y$ 同时向上调整,并保持深度一致且二者不会相会。依次尝试把 $x$, $y$ 同时向上走$k$=$2^{logn}……2^1 ,2^0$步,若$f[x][k]$≠ $f[y][k]$,则令$x=f[x][k],y=f[y][k]$。
⑤此时 $x$,$y$ 必定只差一步就相会了,他们的父节点 $f[x][0]$就是 $LCA$。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 501000
int n,m,s;
int dep[maxn<<];
int f[maxn<<][];
int head[maxn<<],cnt=;
struct hh
{
int nex,to;
}t[maxn<<];
inline void add(int nex,int to)
{
t[++cnt].nex=head[nex];
t[cnt].to=to;
head[nex]=cnt;
}
inline void Deal_first(int u,int fa)
{
dep[u]=dep[fa]+;
for(int i=;i<;i++)
f[u][i+]=f[f[u][i]][i];
for(int i=head[u];i;i=t[i].nex)
{
int v=t[i].to;
if(v==fa) continue;
f[v][]=u;
Deal_first(v,u);
}
return;
}
inline int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)
{
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
}
for(int i=;i>=;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][];
}
inline int read()
{
int kr=,xs=;
char ls;
ls=getchar();
while(!isdigit(ls))
{
if(!(ls^))
kr=-;
ls=getchar();
}
while(isdigit(ls))
{
xs=(xs<<)+(xs<<)+(ls^);
ls=getchar();
}
return xs*kr;
}
int main()
{
int x,y;
n=read();m=read();s=read();
for(int i=;i<n;i++)
{
x=read();y=read();
add(x,y);
add(y,x);
}
Deal_first(s,);
for(int i=;i<=m;i++)
{
x=read();y=read();
printf("%d\n",LCA(x,y));
}
return ;
}
LCA--P3379 【模板】最近公共祖先(LCA)的更多相关文章
- [模板] 最近公共祖先/lca
简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...
- HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...
- Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)
Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...
- POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)
POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- 【lhyaaa】最近公共祖先LCA——倍增!!!
高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...
- 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)
题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...
- 最近公共祖先(LCA)模板
以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖 ...
- luogu3379 【模板】最近公共祖先(LCA) 倍增法
题目大意:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 整体步骤:1.使两个点深度相同:2.使两个点相同. 这两个步骤都可用倍增法进行优化.定义每个节点的Elder[i]为该节点的2^k( ...
- 最近公共祖先lca模板
void dfs(int x,int root){//预处理fa和dep数组 fa[x][0]=root; dep[x]=dep[root]+1; for(int i=1;(1<<i)&l ...
随机推荐
- css的艺术
鲁先生曾经说过:"html和css都不能算一门语言..." html确实不能算一门语言,他只是二三十个英语单词而已,但是css不一样,css是==艺术== 骚操作 上图的12个图标 ...
- PHP 跨域之header
之前的博客里记录了PHP解决跨域的方案:JSONP:https://www.cnblogs.com/pawn-i/p/11899120.html 除了jsonp之后,还是通过header函数设置响应头 ...
- 051、Java中使用while循环实现1~100的累加
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- SQL添加列、非空、默认值
use MarcoBarcode go alter table [dbo].[WorkOrderRepairSheet] ADD needRepair int go ALTER TABLE [dbo] ...
- HttpClient测试
导入maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson&l ...
- 安装phpmyadmin数据可视化
1.下载压缩包,并且解压 cd /usr/local/src wget https://files.phpmyadmin.net/phpMyAdmin/4.9.4/phpMyAdmin-4.9.4-a ...
- 对上一篇Logstash的补充
主要补充内容: 1.同步多表 2.配置的参数个别说明 3.elasticsearch的"_id"如果有相同的,那么会覆盖掉,相同"_id"的数据只会剩下最后一条 ...
- JVM探秘:jstack查看Java线程状态
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. jstack命令可以打印Java进程的各个线程堆栈跟踪信息,可以用来查看Java中各个 ...
- 二十五、JavaScript之查找字符串中的字符串indexOf和lastIndexOf的用法
一.代码如下 二.效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" conten ...
- 逆向-PE重定位表
重定位表 当链接器生成一个PE文件时,会假设这个文件在执行时被装载到默认的基地址处(基地址+RVA就是VA).并把code和data的相关地址写入PE文件.如果像EXE一样首先加载就是它image ...