首页 > 其他分享 >DFS序求LCA

DFS序求LCA

时间:2024-09-24 19:14:10浏览次数:7  
标签:int LCA 序求 DFS dfn lca

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]\)。

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

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

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int long long
using namespace std;
using ll = long long;
const int N = 5e5 + 5;
struct node{
	int v,ne;
}e[N << 1];
int n, m, s, idx = 0, cnt = 0;
int dfn[N], dep[N], fa[N], st[22][N], first[N];
void add(int x, int y){ e[++idx] = (node){y, first[x]}; first[x] = idx; }
int cmin(int x, int y){
	if(dep[x] < dep[y]) return x;
	return y;
}
void dfs(int u,int f){
	dfn[u] = ++cnt;
	st[0][cnt] = u;
	fa[u] = f;
	dep[u] = dep[f] + 1;
	for(int i = first[u]; i; i = e[i].ne){
		int v = e[i].v;
		if(v == f) continue;
		dfs(v, u);
	}
}
int lca(int u,int v){
	if(u == v) return u;
	if((u = dfn[u]) > (v = dfn[v])) swap(u, v);
	int t = __lg(v - u++);
	return fa[cmin(st[t][u], st[t][v - (1 << t) + 1])];
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m >> s;
	F(i, 1, n-1){
		int u, v;
		cin >> u >> v;
		add(u, v),add(v, u);
	}
	dfs(s, 0); 
//	F(i, 1, n) cout << st[0][i] << ' '; cout << '\n';                 
	F(i, 1, 20) for(int j = 1; j + (1 << i) - 1 <= n ; ++j) 
		st[i][j] = cmin(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
	F(i, 1, m){
		int u, v;
		cin >> u >> v;
		cout << lca(u, v) << '\n';
	}
	return 0;
}

参考博客

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

标签:int,LCA,序求,DFS,dfn,lca
From: https://www.cnblogs.com/superl61/p/18429819

相关文章

  • 大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:MergeTree实测案例Re......
  • 【Unity】CinemachineVirtualCamera:实现第一人称视角控制
    相机视角的控制,利用CinemachineVirtualCamera插件(在packageManager中下载)实现键盘和鼠标控制第一人称视角。WASD前进后退向左向右,QE左右旋转;鼠标滚轮控制远近、俯仰和升降。另外还支持鼠标靠近边缘移动、鼠标拖拽等控制方式。成果展示Scene部分主相机增加CinemachineBrain组......
  • Hadoop三大组件之HDFS(一)
    1.HDFS的架构HDFS(HadoopDistributedFileSystem)采用主从架构,由一个NameNode(主节点)和多个DataNode(从节点)组成。NameNode负责管理数据块映射信息(如文件名、文件目录、权限、块位置等)并配置副本策略,而DataNode负责存储实际的数据块。SecondaryNameNode辅助NameNode进行元......
  • 树上差分+lca 黑暗的锁链
    //**太久不写了,感觉很难受。。。比赛最近打得也不好,课内任务又重,还要忙着做项目。何去何从。今天又写了一题,用了树上差分的知识。下面来整理整理。1.首先让我们学一下lca(最小公共父节点) 我用的是倍增来求的。总共其实就是两步:dfs打ST表预处理每个点的上面节点 lca求两......
  • 简单搜索(BFS,DFS,剪枝)一网打尽
    深搜DFS含义深搜是一种遍历或搜索图和树的算法。实现方式(不撞南墙不回头)根据题目选择一个适合的源节点,从源节点开始选择一条路一直走,直到无法前进(不满足题目条件)时,返回到上一个节点重新尝试,直到当前的节点的所有子节点都已经被访问过,再次返回到当前节点的上一节点,继续重复......
  • HBase与HDFS&Hive
    在大数据领域中,HBase和HDFS是两种常用的存储系统。它们各自有其独特的特性和优势,但也有一些关键的差异。理解这些差异可以帮助我们更好地选择适合我们需求的存储解决方案。HBase:HBase是一个分布式列存储数据库,它是ApacheHadoop生态系统的一部分。它以行键为索引,支持高性能的随机......
  • GridFS
     1.概述如果文件大小超过16MB的BSON文档大小限制,可以使用GridFS来存储和检索。GridFS不将文件存储在一个文档中,而是大型数据进行分块处理,然后将这些切分后的小文档保存在数据库中。 2.GridFS的工作原理GridFS在存储桶中组织文件,存储桶是一组包含文件块和描述性信......
  • FastDFS配置文件tracker
    #valu:路径base_path=/home/michael/fdfs/base4trackermax_connections#func:最大连接数#valu:正整数值m一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎徽关注公zhong号:编程进阶路加入我们的的圈子(技术交流、学习资源、职......
  • dfs 油滴拓展——洛谷p1378
    油滴扩展题目描述在一个长方形框子里,最多有\(N\)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这\(N\)个点上放置油滴,才能使放置完毕后所有......
  • (LeetCode 热题 100) 199. 二叉树的右视图(递归、深度优先搜索dfs)
    199.二叉树的右视图思路:递归每次都优先右边子树,然后才是左子树。/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(nullptr),right(nullptr){}......