[LCA]最近公共祖先(倍增)

news2024/11/15 14:06:29

概念引入

在这里插入图片描述

祖先

祖先其实很好理解,一个节点的 **父节点 以及 父节点的父节点 以及 父节点的父节点的父……**都是这个节点的祖先

比如说上面的 d d d 节点, b b b 节点和 a a a 节点都是它的祖先

k k k 级祖先

称节点 𝑥 的父节点为 𝑥 的 1 级祖先。节点 𝑥 父节点的 𝑘 级祖先称为节点 𝑥 的 𝑘 + 1 级祖先。

比如,节点 a a a 就是节点 d d d 的二级祖先

引例

假设节点 i i i k k k 级祖先是 j j j j j j k 1 k1 k1 级祖先为 x x x ,那么 x x x i i i 的几级祖先?

显然是 ( k + k 1 ) (k + k1) k+k1 级祖先

深度

记 𝑑𝑒𝑝(𝑥) 为节点 𝑥 的深度。
若 𝑥 为根结点,则 𝑑𝑒𝑝(𝑥) = 1;
否则 𝑑𝑒𝑝(𝑥) = 𝑑𝑒𝑝(𝑓) + 1,其中 𝑓 为 𝑥 的父节点。

基本思想

考虑树上深度相同的节点对 (𝑥, 𝑦),设其 𝐿𝐶𝐴 为节点 𝐿。
Δ = 𝑑𝑒𝑝 𝑥 − 𝑑𝑒𝑝(𝐿)
显然,Δ > 0,为节点对 (𝑥, 𝑦) 与 𝐿 的深度差,即节点 (𝑥, 𝑦)想要抵达节点 𝐿,需要向上跳跃的距离。

我们只需要求出节点 𝑥 或 𝑦 的 Δ 级祖先,就求出了节点对 (𝑥, 𝑦)的最近公共祖先,但 Δ 具体的值并不明确,采用尝试的办法。
不妨记 𝐹(𝑥, 𝑘)(𝑘 ≥ 0) 为节点 𝑥 的 2 k 2^k 2k 级祖先。
由倍增思想,从高位 ( l o g 2 n ) (log_2 n) (log2n)向低位( 0 0 0)依次枚举 𝑖。
若 𝐹 𝑥, 𝑖 = 𝐹(𝑦, 𝑖),说明 𝑥 的 2 i 2^i 2i 级祖先在节点 𝐿 到根节点的路
径上,不作处理。
否则,𝑥 ← 𝐹 𝑥, 𝑖 , 𝑦 ← 𝐹(𝑦, 𝑖)。
当 𝑖 = 0 枚举完毕后,𝑥, 𝑦 节点的父节点即为其最近公共祖先。

代码实现

𝐹(𝑥, 𝑘) 则可以通过递推在预处理中求出。
F ( x , 0 ) = f F(x,0) = f F(x,0)=f
F ( x , k ) = F ( F ( x , k − 1 ) , k − 1 ) ) F(x,k) = F ( F(x,k-1),k-1)) F(x,k)=F(F(x,k1),k1))
这可以通过一次树上遍历完成。
若 𝑑𝑒𝑝 𝑥 ≠ 𝑑𝑒𝑝(𝑦),不妨设 𝑑𝑒𝑝(𝑥) > 𝑑𝑒𝑝(𝑦),先通过一次倍增,将节点 𝑥 向上跳跃至与节点 𝑦 深度相同。

C o d e Code Code

#include <bits/stdc++.h>
#define ll long long
const int INF = 0x3f3f3f3f;
const int N = 5e5+10; 
using namespace std;
int n, m , s;
vector <int> e[N];
int fa[N][25],dep[N];
void get_father(int pos,int f){
	fa[pos][0] = f;
	dep[pos] = dep[f] + 1;
	for(int i = 1; i <= 20; i++){
		fa[pos][i] = fa[fa[pos][i-1]][i-1];
	}
	for(auto j : e[pos]){
		if(j == f) continue;
		get_father(j,pos);
	}
}
int LCA(int x, int y){
	if(dep[x] < dep[y]){
		swap(x,y);
	}
	for(int i = 20; i >= 0; i--){
		if(dep[fa[x][i]] >= dep[y]){
			x = fa[x][i];
		}
	}
	if(x == y) return x;
	for(int i = 20; i >= 0; i--){
		if(fa[x][i] != fa[y][i]){
			x = fa[x][i];
			y = fa[y][i];
		}
	}
	return fa[x][0];
}
int main(){
	cin >> n >> m >> s;
	for(int i = 1;i < n; i++){
		int u, v;
		cin >> u >> v;
		e[u].push_back(v);
		e[v].push_back(u);
	}	
	get_father(s,0);
	while(m--){
		int x, y;
		cin >> x >> y;
		cout << LCA(x,y) << endl;
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/420423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你走进Flutter 3.7

期待已久的新教程上线啦&#xff01;解锁Flutter开发新姿势&#xff0c;一网打尽Flutter最新与最热技术&#xff0c;点我Get!!! 新年伊始&#xff0c;由 Flutter 3.7 正式版来「打头阵」&#xff01;我们与整个 Flutter 社区们继续在 Flutter 3.7 中优化了框架&#xff0c;包括…

(一)Linux:自由、开放、灵活的操作系统内核

目录 一、Linux的发展史 二、linux的开源 三、目前的现状 四、企业应用现状 五、发行的版本 六、安装与使用 七、利用云服务器配置Linux环境 一、Linux的发展史 Linux是一款由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;开发的操作系统内核&#xff0c;它的发布…

用 logging 模块将信息输出到日志文件

当你要用到一些信息去统计画图&#xff0c; 或者你的输出太长了&#xff0c;出现了那种“折叠”&#xff0c;就是说“内容超过1000行”&#xff0c;结果等下一次进入环境&#xff0c;你只能看到结尾的输出&#xff0c;却看不到开头的输出了&#xff0c; 那么你可以使用 Pytho…

【NLP实战】基于Bert和双向LSTM的情感分类【上篇】

文章目录前言简介数据获取与提取数据清洗读取数据&#xff0c;查看数据清洗训练集观察数据分布去除空数据去除重复数据关于去除停用词关于特殊符号储存清洗后的数据集清洗测试集观察数据分布去除空数据去除重复数据(并储存)清洗验证集观察数据分布去除空行去除重复数据(并储存)…

Go分布式爬虫(二十四)

文章目录24 存储引擎爬取结构化数据step1 从首页获取热门标签信息step2 获取图书列表step3 获取图书详情完整规则存储到MySQL数据抽象数据存储存储引擎实现存储引擎验证dockerdocker-compose使用Navicat查看使用DataGrip查看24 存储引擎 爬虫项目的一个重要的环节就是把最终的…

Mysql逻辑架构和语句执行流程

文章目录1. 逻辑架构剖析1.1 连接管理--连接层1.2 解析与优化--服务层1.3 存储引擎2. SQL语句的执行流程2.1 执行原理2.2 语法顺序1. 逻辑架构剖析 当一个客户端连接mysql服务器执行一条查询语句时&#xff0c;会发生以下处理过程&#xff1a; 1.1 连接管理–连接层 客户端想…

1.半导体基础知识

1.半导体基础知识本征半导体什么是半导体&#xff1f;什么是本征半导体&#xff1f;本征半导体的结构本征半导体中的两种载流子为什么将自然界导电性能中等的半导体材料制成本征半导体杂质半导体N型半导体P型半导体PN结PN结中的扩散运动漂移运动和PN结的形成PN结的单向导电性PN…

Spring中Bean对象的作用域和生命周期详解

Spring作为一个具有众多工具方法的IoC容器&#xff0c;其核心功能就是Bean对象的存储和取出&#xff0c;那么学习Bean对象的作用域和生命周期能让我们更清楚地了解Bean对象在Spring容器中的整个加载过程&#xff01; 一&#xff0c;案例演示&#xff08;Bean对象的修改&#xf…

4.搜索辅助功能

ES 既有基本的搜索功能、又有字段类型的精确搜索、分词匹配、范围搜索、坐标搜索、分页查询等等。 4.1 搜索辅助功能 俗话说“工欲善其事&#xff0c;必先利其器”。在介绍ES提供的各种搜索匹配功能之前&#xff0c;我们先介绍ES提供的各种搜索辅助功能。例如&#xff0c;为优化…

【让你的灵感立刻落地】在线代码运行平台InsCode

文章目录官网地址详解1. 导入项目2. 在线演示、在线修改3. 发布作品参考InsCode 是一个在线代码运行平台&#xff0c;可以在线上运行代码&#xff0c;并且支持多种语言&#xff0c;同时还可以在线修改和提交代码&#xff0c;支持发布和分享项目。InsCode 平台在编写博客、演示项…

二叉树练习题(递归展开图详解哦)

全文目录引言单值二叉树题目描述及思路实现二叉树的最大深度题目描述及思路实现翻转二叉树题目描述及思路实现相同的树题目描述及思路实现总结引言 前面我们介绍了二叉树的相关基础知识&#xff0c;并且了解到二叉树的表示有两种结构&#xff1a;顺序结构与链式结构。即&#…

手把手教您注册/使用Claude

文章目录注册slack注意事项最近几天出现了一个很火的AI聊天项目——Claude&#xff0c;据说可以媲美ChatGPT&#xff0c;最主要的就是可以很好的解决我们国内的使用痛点&#xff0c;可以完全免费无限制的使用&#xff0c;下面就和大家分享一下正确的注册和使用Claude的流程&…

想成为一名【黑客】,你该如何快速的入门?

假设你有一台个人电脑&#xff0c;或者可以访问一台电脑&#xff0c;那么你就可以着手【黑客】技能的学习了。【黑客】文化演化而来的的时候&#xff0c;电脑是很昂贵的&#xff0c;个人不能拥有他们。所以最重要的一个步骤就是新手可以拥有一台属于自己的电脑&#xff0c;新手…

【Cisco Packet Tracer| 一.交换机配置模式与基本参数配置】

文章目录一.交换机的多种模式以及切换1.如何进入到交换机配置的命令行用户界面(Command Line Interface)2.普通模式模式3.特权用户模式4.全局配置模式5.模式切换图二.交换机名称&#xff0c;口令等设置1.全局模式下-交换机改名2.接口模式下-配置端口速度和工作模式2.1配置端口速…

项目8:用户注册和登录的前后端联调

项目8&#xff1a;用户注册和登录的前后端联调 1.前端项目使用 2.前端项目注册模块 3.后端完成项目注册 4.前端项目登录模块 5.后端完成项目登录 6.用户认证&#xff08;校验用户是否登录&#xff09; 项目8&#xff1a;用户注册和登录的前后端联调 1.前端项目使用 直接…

20230413在CV1826平台配置开机自启动程序

20230413在CV1826平台配置开机自启动程序 2023/4/13 10:51 1、项目需求&#xff1a;硬件需要测量摄像头开机之后的电压/时钟信号&#xff0c;但是不想每次开机的时候都通过adb连接cv1826来开启摄像头。 C:\Users\Sun>adb shell / # / # cd /mnt/ /mnt # /mnt # ls -l total …

Go 语言性能优化指南

编写高性能的 Go 程序~ 前言&#xff1a; 继上次课程的高质量编程内容讲解&#xff0c;本次课程主要介绍了在满足正确性、可靠性、健壮性、可读性等质量因素的前提下提高程序效率的性能优化建议&#xff1b;性能优化分析工具&#xff1b;以及性能调优的实战案例&#xff0c;分…

叶酸聚乙二醇羟基FA-PEG-OH;一文带你了解高分子试剂OH-PEG-Folate

FA-PEG-OH&#xff0c;叶酸-聚乙二醇-羟基 中文名称&#xff1a;叶酸聚乙二醇羟基 英文名称&#xff1a;FA-PEG-OH HO-PEG-FA Folate-PEG-OH 性状&#xff1a;黄色液体或固体&#xff0c;取决于分子量 溶剂&#xff1a;溶于水&#xff0c;DMSO、DMF等常规性有机溶剂 活性基…

城市地下综合管廊安全运营与智慧管控的分层架构研究

安科瑞 李亚俊 1、引言 1833年&#xff0c;市政管线综合管廊在巴黎城市地下建成至今&#xff0c;经过百年来的探索、研究、改良和实践&#xff0c;法国、英国、德国、俄罗斯、日本、美国等发达国家的管廊规划建设与安全运维体系已经日臻完善&#xff0c;截止目前&#xff0c;…

《花雕学AI》17:关注提示工程—本世纪最重要的技能可能就是与AI人工智能对话

本文目录与主要结构 引言&#xff1a;介绍提示工程的概念和背景&#xff0c;说明为什么它是本世纪最重要的技能之一。 正文&#xff1a; 一、提示工程的基本原理和方法&#xff1a;介绍什么是提示、如何设计和优化提示、如何使用提示与语言模型进行交互。 二、提示工程的应用和…