DFS序求LCA

介绍

欧拉序求LCA 的数组总是会忘记开两倍,并且预处理的常数较大。用 DFS序求LCA 可以解决这些问题。

欧拉序:进节点和出节点会重复记录节点。

DFS序:深度优先搜索的顺序,不会重新记录。

假设要求 \(lca(u,v)\), 且 \(dfn[u] < dfn[v]\)。

那么 \(dfn[u] \sim dfn[v]\) 的所有点都在 \(lca(u,v)\) 子树中。

其中包括 \(lca\) 在 \(v\) 方向上的第一个点 \(x\), 显然这个点是 \(dfn[u] \sim dfn[v]\) 中 \(dep\) 最小的,和 欧拉序求LCA 一样, 我们用 st表 找到这个位置就可以,min函数改为 比较dep。

这样就找到了 \(x\), 那么 \(lca(u,v) = fa[x]\)。

说明: 找 \(x\) 的原因是因为 \(lca\) 的 \(dfn\) 不一定在这个范围内。

还有一种不用记录 \(dep\) 仅依靠 \(dfn\) 求解 lca 的小技巧:\(dfn\) 改为记录每个点的父节点, 最终 st表求出的值就是 lca。(详情见参考博客)

\(dfn[u] + 1\) 的原因是考虑到了 \(u, v\) 在同一条链上的情况。

【模板】最近公共祖先(LCA)

struct LCA{
struct node{
int v, ne;
}e[N << 1];
int first[N], idx = 0;
int dep[N], fa[N], dfn[N], rev[22][N], cnt = 0;
void add(int x, int y){
e[++ idx] = (node){y, first[x]};
first[x] = idx;
}
void dfs(int u, int f){
fa[u] = f;
dep[u] = dep[f] + 1;
dfn[u] = ++ cnt;
rev[0][cnt] = u;
for(int i = first[u]; i; i = e[i].ne){
int v = e[i].v;
if(v == f) continue;
dfs(v, u);
}
}
int cmin(int x, int y){
if(dep[x] < dep[y]) return x;
return y;
}
int getlca(int x, int y){
if(x == y) return x;
if((x = dfn[x]) > (y = dfn[y])) swap(x, y);
int t = __lg(y - x++);
return fa[cmin(rev[t][x], rev[t][y - (1 << t) + 1])];
}
void init(){
dfs(root, 0);
F(j, 1, 20) F(i, 1 , n - (1 << j) + 1) rev[j][i] = cmin(rev[j - 1][i], rev[j - 1][i + (1 << (j - 1))]);
}
}lca;

参考博客

冷门科技 —— DFS 序求 LCA - By Alex_Wei

DFS序求LCA的更多相关文章

  1. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  2. D - Project Presentation(DFS序+倍增LCA)

    You are given a tree that represents a hierarchy in a company, where the parent of node u is their d ...

  3. dfs序 + RMQ = LCA

    dfs序是指你用dfs遍历一棵树时,每个节点会按照遍历到的先后顺序得到一个序号.然后你用这些序号,可以把整个遍历过程表示出来. 如上图所示,则整个遍历过程为1 2 3 2 4 5 4 6 4 2 1 ...

  4. bzoj 2819 Nim(BIT,dfs序,LCA)

    2819: Nim Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1596  Solved: 597[Submit][Status][Discuss] ...

  5. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

  6. Codeforces Round #384 (Div. 2) A B C D dfs序+求两个不相交区间 最大权值和

    A. Vladik and flights time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  7. 蓝皮书:异象石 【dfs序+lca】

    题目详见蓝皮书[算法竞赛:进阶指南]. 题目大意: 就是给你一颗树,然后我们要在上面进行三种操作:  1.标记某个点  或者  2.撤销某个点的标记  以及   3.询问标记点在树上连通所需的最短总边 ...

  8. BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )

    虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...

  9. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  10. 【BZOJ3772】精神污染 DFS序+主席树

    [BZOJ3772]精神污染 Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是 ...

随机推荐

  1. Codeforces Round 911 (Div. 2) D

    Codeforces Round 911 (Div. 2) D D. Small GCD 题意 定义\(f(a,b,c)\)为\(a,b,c\)中较小两个数的\(gcd\),给定数组\(a_{1... ...

  2. 一文搞懂Cortex-A9 ADC裸机和基于Linux驱动编写方法

    前言 在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9 Linux内核:3.14 在讲述AD ...

  3. 如何将一个模块文件编译到Linux内核中?

    很多粉丝在群里提问,如何把一个模块文件编译到内核中或者独立变异成ko文件.本文给大家详解讲解. 1. 内核目录 Linux内核源代码非常庞大,随着版本的发展不断增加.它使用目录树结构,并且使用Make ...

  4. kubernetes批量删除evicted状态pod

    #!/bin/bash # get namespace namespaces=`kubectl get pod -A | grep -i "evicted" | awk '{pri ...

  5. JavaScript设计模式样例九 —— 桥接模式

    桥接模式(Bridge Pattern) 定义:是用于把抽象化与实现化解耦,使得二者可以独立变化. 目的:将抽象部分与实现部分分离,使它们都可以独立的变化. 场景:实现系统可能有多个角度分类,每一种角 ...

  6. OBS直播抠绿插件(Matting123)

    一.产品概述 OBS直播抠绿插件(Matting123)是使用绿幕.蓝幕进行抠像的虚拟直播软件,本软件需要配合OBS30.0.0或以上版本进行使用.Matting123采用自研抠图算法,该算法已达到影 ...

  7. Vue状态管理库Pinia详解

    Pinia 是 Vue 的状态管理库,它提供了一种更简单.更不规范的 API 来管理应用的状态.Pinia 的设计哲学是简单性和易用性,它避免了 Vuex 中的许多复杂概念,如 mutations 和 ...

  8. 搭建QT开发环境

    下载 Qt官网,Qt下载网址 安装前要登录账号,其他的该咋就咋样,路径不能有中文. 组件自己选 我的是MinGW.Android.虚拟键盘.Qt脚本.Qt Creator 然后创个项目,能跑起来就是安 ...

  9. .NET 开源实时监控系统 - WatchDog

    前言 在平时的开发中随着我们系统应用不断地迭代变的复杂,对应用的实时监控变得越来越重要.实时监控不仅可以帮助我们快速定位问题,还能在出现问题时及时采取措施,减少业务中断的时间. 本文将介绍一个名为Wa ...

  10. C# 导出datatable数据到excel

    第一步:下载两个需要的NUGET包 1.org.in2bits.MyXls:2.NPOI 第二步:关键类OutExcel. using System; using System.Linq; using ...