LCA 在线倍增法 求最近公共祖先
第一步:建树 这个就不说了
第二部:分为两步 分别是深度预处理和祖先DP预处理
DP预处理:
int i,j;
for(j=;(<<j)<n;j++)
for(int i=;i<n;++i)
if(fa[i][j]=-)
fa[i][j]=fa[fa[i][j-]][j-];/*DP处理出i的2^j祖先是谁*/
深度预处理:
void dfs(int now,int from,int deepth)
{
deep[now]=deepth;
for(int i=head[now];i;i=e[i].pre)
if(e[i].v!=from)
dfs(e[i].v,now,deepth+);
}
第三部分:LCA核心
int LCA(int a,int b)// 求a、b的最近公共祖先
{
int i,j;
if(deep[a]<deep[b]) swap(a,b); // 保证a的深度比b大这样便于操作
for(i=;(<<i)<=deep[a];++i);// (1<<i) 等同于2的i次方
i--;
for(j=i;j>=;j--)
if((deep[a]-(<<j))>=deep[b])// 让a节点往上蹦 直到a、b晚上一蹦就重合
a=fa[a][j];
if(a==b)return a;// 如果a的一个祖先恰好是b
for(j=i;j>=;j--)
if(fa[a][j]!=-&&fa[a][j]!=fa[b][j])// 没有越界并且祖先不同 那么就让a,b同时往上蹦
{
a=fa[a][j];
b=fa[b][j];
}
return fa[a][];
}
默写的代码:
void DP {
int i,j;
for(int j=; (<<j)<n; j++) {
for(int i=; i<n; i++)
if(fa[i][j]=-)
fa[i][j]=fa[fa[i][j-]][j-];
}
}
void dfs(int now,int deepth,int from) {
deep[now]=deepth;
for(int i=head[now]; i; i=e[i].next) {
if(e[i].v!=from) {
dfs(e[i].v,deepth+,now);
}
}
}
int LCA(int a,int b) {
int i,j;
if(deep[a]<deep[b]) swap(a,b);
for(i=; (<<i)<=deep[a]; i++);
i--;
for(j=i; j>=; j--) {
if(deep[a]-(<<j)>=deep[b])
a=fa[a][j];
}
if(a==b) return a;
for(j=i; j>=; j--) {
if(fa[a][j]!=-&&fa[a][j]!=fa[b][j]) {
a=fa[a][j];
b=fa[b][j];
}
}
return fa[a][];
}
LCA 在线倍增法 求最近公共祖先的更多相关文章
- 用“倍增法”求最近公共祖先(LCA)
1.最近公共祖先:对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.的祖先且x的深度尽可能大. 2.朴素算法:记录下每个节点的父亲,使节点u,v一步一步地向上找 ...
- 在线倍增法求LCA专题
1.cojs 186. [USACO Oct08] 牧场旅行 ★★ 输入文件:pwalk.in 输出文件:pwalk.out 简单对比时间限制:1 s 内存限制:128 MB n个被自 ...
- 倍增法求lca(最近公共祖先)
倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...
- 倍增法求LCA
倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...
- 树上倍增法求LCA
我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题 ...
- 【LCA求最近公共祖先+vector构图】Distance Queries
Distance Queries 时间限制: 1 Sec 内存限制: 128 MB 题目描述 约翰的奶牛们拒绝跑他的马拉松,因为她们悠闲的生活不能承受他选择的长长的赛道.因此他决心找一条更合理的赛道 ...
- HDU 2586 倍增法求lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)
题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...
- RMQ(倍增法求ST)
解决什么问题:区间查询最值 倍增思想:每次得出结果的范围呈2的幂次增长,有人说相当于二分,目前我觉得相当于线段树的查找. 具体理解看代码: /*倍增法求ST*/ #include<math.h& ...
随机推荐
- AJPFX总结java InputStream读取数据问题
1. 关于InputStream.read() 在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方法是从流里每次只读取读取一个字节,效率会非常低. ...
- Java长存!12个Java长久占居主要地位的原因
Java长存!12个Java长久占居主要地位的原因 我们很容易就会遗忘那些曾经在猿群中大热而又被各种新技术掩盖直至堙灭的技术的价值.就拿COBOL这个老猿们当年所用的神器来说,就跟条死鱼一样被现代猿基 ...
- Es6里面的解析结构
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Keil Debug (printf) Viewer
Debug (printf) Viewer Home » µVision Windows » Debug (printf) Viewer The Debug (printf) Viewer windo ...
- Tomcat启动报错 ERROR org.apache.struts2.dispatcher.Dispatcher - Dispatcher initialization failed
背景: 在进行Spring Struts2 Hibernate 即SSH整合的过程中遇到了这个错误! 原因分析: Bean已经被加载了,不能重复加载 原来是Jar包重复了! 情形一: Tomcat ...
- ionic小白的学习路之目录结构分析、创建组件、创建页面、页面跳转
一. 目录结构分析 hooks:编译cordova 时自定义的脚本命令,方便整合到我们的编译系统和版本控制系统中. node_modules :node 各类依赖包. resources :andro ...
- shell $() vs ${}
reference $( )与` `(反引号)都是用来做命令替换(command substitution)用的 run command 3, 2, 1 command1 $(command2 $(c ...
- spring中bean的配置详解--定义parent
在工作中碰到了好多的配置文件,具体来说是spring 中bean配置的parent的配置,搞的我一头雾水,仔细看一下spring中有关bean的配置,剖析一下,具体什么含义! 一.Spring IoC ...
- eclipse修改SVN账号密码
首先,eclipse中打开window------>preferences------->SVN页面,如下所示: 注意我圈起来的地方,JavaHL是不可用的,因此SVN接口应该是SVNKi ...
- 【mybatis】mybatis数据源源码剖析(JNDI、POOLED、UNPOOLED)
一.概述 二.创建 mybatis数据源的创建过程稍微有些曲折. 1. 数据源的创建过程: 2. mybatis支持哪些数据源,也就是dataSource标签的type属性可以写哪些合法的参数? 弄清 ...