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& ...
随机推荐
- 2. UITest相关APIs
1. XCUIApplication 这是你正在测试的应用的代理.它能让你启动应用,这样你就能执行测试了.它每次都会新起一个进程,这会多花一些时间,但是能保证测试应用时的状态是干净的,这样你需要处理的 ...
- Windows 2016 安装Sharepoint 2016 预装组件失败
Windows 2016 安装Sharepoint 2016 预装组件失败 日志如下: -- :: - Request for install time of Web 服务器(IIS)角色 -- :: ...
- Javascript异步编程的常用方法
Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任 ...
- gulp自动化构建工具使用
gulpfile.js: var gulp = require("gulp"); var imagemin = require("gulp-imagemin") ...
- 聊聊JavaScript和Scala的表达式 Expression
我们先看下面这段简单的JavaScript代码. 我在第10行调用了函数f,其中传入的第二个和第三个参数都是一个逗号表达式. 函数f的实现,会检查这两个参数的类型,如果是函数,则执行函数调用,再打印其 ...
- 微信小程序开发系列四:微信小程序之控制器的初始化逻辑
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 这个教程的前两篇文章,介绍了如何 ...
- 手把手教你免费把网站IP换成1.1.1.1/1.0.0.1
近日,Cloudflare官方发文,与APNIC官方合作打算用IP1.1.1.1推出速度更快.私密性更强的DNS Cloudflare 运行全球规模最大.速度最快的网络之一. APNIC 是一个非营利 ...
- 云原生技术图谱 (CNCF Landscape)
转自:https://raw.githubusercontent.com/cncf/landscape/master/landscape/CloudNativeLandscape_latest.jpg
- varchar2(100 char)是什么意思
最佳答案 varchar2(100 char)最长可以插入100个任意字符而varchar2(100)最长可以插入100个英文字符
- docker使用阿里云镜像加速器(属于自己的专属加速器)
https://cr.console.aliyun.com/cn-shanghai/mirrors