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& ...
随机推荐
- apt-get的一些坑
apt-get update:更新安装列表apt-get upgrade:升级软件apt-get install software_name :安装软件apt-get --purge remove ...
- Oracle EXPDP and IMPDP
一.特点 • 可通过 DBMS_DATAPUMP 调用 • 可提供以下工具: – expdp – impdp – 基于 Web 的界面 • 提供四种数据移动方法: – 数据文件复制 – 直接路径 – ...
- SEO 第八章
SEO第八章 本次课目标: 1. 网站外部优化的外链优化 2. 网站流量分析 1. 什么叫做外链? 外链也叫反向链接,指的是从别的网站指向我自己的网站的链接. 2. 外链的作用? l 外链可 ...
- wkhtmltopdf导出html到pdf
1.使用背景 最近公司需要把html页面的内容生成pdf并下载,试过很多方法都没有满意的效果,后来找到wkhtmltopdf这款软件,终于解决了这个问题. wkhtmltopdf是exe文件, ...
- docker存储管理
Docker 镜像的元数据 repository元数据 repository在本地的持久化文件存放于/var/lib/docker/image/overlay2/repositories.json中 ...
- android打包需要的图标
ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12 大小: 32x32.png 48 72 96 144
- c++调用com口操作autocad
#include "stdafx.h" #include <atlcomcli.h> #import "D:\\C++test\\FirstCom\\Rele ...
- python基础一 day2
内容: 3%%s 输出:3%s 后面的全部转义 结果: 如果是因为执行break语句导致循环提前结束,就不会执行else. 单位换算: 编码方式: ascii unicode u ...
- sh脚本写法
1.shell注释符号: 1. 单行注释: “#” 2. 多行注释: : << ! 语句1 语句2 语句3 语句4 ! http://blog.csdn.net/lansesl2008/a ...
- zay大爷的膜你题 D2T1 江城唱晚
依旧是外链... 这一次网易云爆炸了....所以我决定后面的都用QQ 下面是题面 这道题是一道傻逼题 数学题,我们仔细看一看,首先有m朵花的话,我们就有m!种排列方式(也就是m的全排列), 然后我们假 ...