当前位置: 首页 > news >正文

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

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

https://www.luogu.com.cn/problem/P3379

题目描述

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

输入格式

第一行包含三个正整数 N , M , S N,M,S N,M,S,分别表示树的结点个数、询问的个数和树根结点的序号。

接下来 N − 1 N-1 N1 行每行包含两个正整数 x , y x, y x,y,表示 x x x 结点和 y y y 结点之间有一条直接连接的边(数据保证可以构成树)。

接下来 M M M 行每行包含两个正整数 a , b a, b a,b,表示询问 a a a 结点和 b b b 结点的最近公共祖先。

输出格式

输出包含 M M M 行,每行包含一个正整数,依次为每一个询问的结果。

样例 #1

样例输入 #1
5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5
样例输出 #1
4
4
1
4
4

提示

对于 30 % 30\% 30% 的数据, N ≤ 10 N\leq 10 N10 M ≤ 10 M\leq 10 M10

对于 70 % 70\% 70% 的数据, N ≤ 10000 N\leq 10000 N10000 M ≤ 10000 M\leq 10000 M10000

对于 100 % 100\% 100% 的数据, 1 ≤ N , M ≤ 500000 1 \leq N,M\leq 500000 1N,M500000 1 ≤ x , y , a , b ≤ N 1 \leq x, y,a ,b \leq N 1x,y,a,bN不保证 a ≠ b a \neq b a=b

样例说明:

该树结构如下:

image-20241205172110403

第一次询问: 2 , 4 2, 4 2,4 的最近公共祖先,故为 4 4 4

第二次询问: 3 , 2 3, 2 3,2 的最近公共祖先,故为 4 4 4

第三次询问: 3 , 5 3, 5 3,5 的最近公共祖先,故为 1 1 1

第四次询问: 1 , 2 1, 2 1,2 的最近公共祖先,故为 4 4 4

第五次询问: 4 , 5 4, 5 4,5 的最近公共祖先,故为 4 4 4

故输出依次为 4 , 4 , 1 , 4 , 4 4, 4, 1, 4, 4 4,4,1,4,4

2021/10/4 数据更新 @fstqwq:应要求加了两组数据卡掉了暴力跳。

代码

倍增算法
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
vector<vector<int>> e;   // 存储每个节点连接的边
vector<vector<int>> fa;  // 存储节点的跳跃情况
vector<int> dep;         // 存储节点的深度void dfs(int x, int y) {dep[x]   = dep[y] + 1;  // 深度加1fa[x][0] = y;           // 确认父节点// 从前往后推出父节点for (int i = 1; i <= 18; i++) {fa[x][i] = fa[fa[x][i - 1]][i - 1];}// 递归遍历for (auto i : e[x]) {// 如果不是父节点,那么就dfsif (i != y) dfs(i, x);}
}int lca(int u, int v) {// 首先保证u深度更大if (dep[u] < dep[v]) swap(u, v);// 将u和v深度对齐for (int i = 18; ~i; i--) {// 一直往上跳,不断接近vif (dep[fa[u][i]] >= dep[v]) {u = fa[u][i];}}// 如果u和v相等,那么直接返回vif (u == v) return v;// 否则一起向上寻找lcafor (int i = 18; ~i; i--) {if (fa[u][i] != fa[v][i]) {u = fa[u][i];v = fa[v][i];}}// 因为一定会到lca的下一层,所以直接返回最后的父节点return fa[u][0];
}void solve() {// N为树的节点个数,M为询问个数,S为根节点序号int N, M, S;cin >> N >> M >> S;e.resize(N + 1);fa.resize(N + 1);for (int i = 0; i <= N; i++) {// N最大为500000,所以深度最高为2的18次方,19就会越界fa[i].resize(19);}dep.resize(N + 1, 0);  // 初始化深度为0// 输入N-1个边for (int i = 1; i <= N - 1; i++) {int a, b;cin >> a >> b;// 最开始无向,所以两个都要插入e[a].push_back(b);e[b].push_back(a);}dfs(S, 0);// 输入M个查询for (int i = 1; i <= M; i++) {int u, v;cin >> u >> v;// 寻找lcacout << lca(u, v) << endl;}
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);solve();return 0;
}
tarjan算法
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
vector<bool> vis;                      // 用来存储是否已经访问
vector<vector<int>> e;                 // 存储每个节点连接的边
vector<int> fa;                        // 存储节点的父节点
vector<vector<pair<int, int>>> query;  // 存储要查询的
vector<int> ans;                       // 存储结果
// 并查集——路径压缩
int find(int u) {if (u == fa[u]) return u;return fa[u] = find(fa[u]);
}void tarjan(int u) {// 首先标记已经访问vis[u] = true;// 访问该节点的所有子节点for (int v : e[u]) {// 不能访问已经访问过的节点if (!vis[v]) {// 递归tarjantarjan(v);// 明确父节点fa[v] = u;}}// 在离开时查询for (auto q : query[u]) {int v = q.first;int i = q.second;// 如果该节点的另一半也访问过了,那么说明现在可以找到共同祖先if (vis[v]) {ans[i] = find(v);}}
}void solve() {// N为树的节点个数,M为询问个数,S为根节点序号int N, M, S;cin >> N >> M >> S;fa.resize(N + 1);vis.resize(N + 1);e.resize(N + 1);query.resize(M + 1);ans.resize(M + 1);// 初始化每个节点的父节点为自己iota(fa.begin(), fa.end(), 0);// 输入N-1个边for (int i = 1; i <= N - 1; i++) {int a, b;cin >> a >> b;// 最开始无向,所以两个都要插入e[a].push_back(b);e[b].push_back(a);}// 输入M个查询for (int i = 1; i <= M; i++) {int u, v;cin >> u >> v;// tarjan为离线算法,所以要先存储查询query[u].push_back({ v, i });query[v].push_back({ u, i });}// tarjantarjan(S);// 输出存储的结果for (int i = 1; i <= M; i++) {cout << ans[i] << endl;}
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);solve();return 0;
}
  • 并查集的路径压缩:路径压缩的基本思想是,在执行查找操作时,将访问路径上的所有节点直接连接到根节点上。这样做的目的是在下一次查找操作时,能直接访问到根节点,从而减少路径长度,提高查找效率。

    // 并查集——路径压缩
    int find(int u) {if (u == fa[u]) return u;return fa[u] = find(fa[u]);
    }
    

相关文章:

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

【模板】最近公共祖先&#xff08;LCA&#xff09; https://www.luogu.com.cn/problem/P3379 题目描述 如题&#xff0c;给定一棵有根多叉树&#xff0c;请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含三个正整数 N , M , S N,M,S N,M,S&#xff0c;分别表示…...

2030. gitLab A仓同步到B仓

文章目录 1 A 仓库备份 到 B 仓库2 B 仓库修改main分支的权限 1 A 仓库备份 到 B 仓库 #!/bin/bash# 定义变量 REPO_DIR"/home/xhome/opt/git_sync/zz_xx_xx" # 替换为你的本地库A的实际路径 REMOTE_ORIGIN"http://192.168.1.66:8181/zzkj_software/zz_xx_xx.…...

网易博客旧文-----如何在WINDOWS下载安卓(android)源代码并和eclipse做关联

如何在WINDOWS下载安卓&#xff08;android&#xff09;源代码并和eclipse做关联 2013-02-05 17:27:16| 分类&#xff1a; 安卓开发 | 标签&#xff1a; |举报 |字号大中小 订阅 编写安卓程序时&#xff0c;有时想看看安卓某些类的实现&#xff0c;但默认情况下环境是不带的。…...

MATLAB中axes函数用法

目录 语法 说明 示例 在图窗中定位多个坐标区 将坐标区设置为当前坐标区 在选项卡上创建坐标区 axes函数的功能是创建笛卡尔坐标区。 语法 axes axes(Name,Value) axes(parent,Name,Value) ax axes(___) axes(cax) 说明 axes 在当前图窗中创建默认的笛卡尔坐标区&…...

构建 Java Web 应用程序:实现简单的增删查改(Mysql)

简介 本教程将指导您如何使用Java Servlet和JSP技术构建一个简单的Web应用程序。该应用程序将包括用户注册、登录、注销&#xff08;删除用户信息&#xff09;、修改密码以及根据性别查询用户信息等功能。我们将使用MySQL数据库来存储用户数据。 环境准备 Java Development …...

3d行政区划-中国地图

前言 技术调研&#xff1a;做底代码平台的3d行政区组件 写的demo 效果图&#xff1a; 实现的功能项 地标、打点、飞线、three.js 3d 中国地图的一些基础配置补充 geo中国地图文件获取 其他项:包 "dependencies": {"d3": "^7.9.0","d3-…...

适合存储时序数据的数据库和存储系统

时序数据的存储通常要求高效地处理大量按时间排序的数据&#xff0c;同时支持快速查询、实时分析和高并发写入。以下是一些适合存储时序数据的数据库和存储系统&#xff1a; 1. InfluxDB 概述&#xff1a;InfluxDB 是一个开源的时序数据库&#xff0c;专门为处理时序数据而设…...

dolphinscheduler集群服务一键安装启动实现流程剖析

1.dolphinscheduler的安装部署 dolphinscheduler服务的安装部署都是非常简单的&#xff0c;因为就服务本身而言依赖的服务并不多。 mysql / postgresql。由于需要进行元数据及业务数据的持久化存储所以需要依赖于数据库服务&#xff0c;数据库服务支持mysql、postgresql等&am…...

深入了解Linux —— 学会使用vim编辑器

前言 学习了Linux中的基本指令也理解了权限这一概念&#xff0c;但是我们怎么在Linux下写代码呢&#xff1f; 本篇就来深入学习Linux下的vim编辑器&#xff1b;学会在Linux下写代码。 软件包管理器 1. 软件包&#xff1f; 在Linux下安装软件&#xff0c;通常是下载程序的源码…...

C05S01-Web基础和HTTP协议

一、Web基础 1. Web相关概念 1.1 URL URL&#xff08;Uniform Resource Locator&#xff0c;统一资源定位符&#xff09;&#xff0c;是一种用于在互联网上标识和定位资源的标准化地址&#xff0c;提供了一种访问互联网上特定资源的方法。URL的基本格式如下所示&#xff1a;…...

MIT工具课第六课任务 Git基础练习题

如果您之前从来没有用过 Git&#xff0c;推荐您阅读 Pro Git 的前几章&#xff0c;或者完成像 Learn Git Branching 这样的教程。重点关注 Git 命令和数据模型相关内容&#xff1b; 相关内容整理链接&#xff1a;Linux Git新手入门 git常用命令 Git全面指南&#xff1a;基础概念…...

计算机网络安全

从广义来说&#xff0c;凡是涉及到网络上信息的机密性、报文完整性、端点鉴别等技术和理论都是网络安全的研究领域。 机密性指仅有发送方和接收方能理解传输报文的内容&#xff0c;而其他未授权用户不能解密&#xff08;理解&#xff09;该报文报文完整性指报文在传输过程中不…...

Delphi 实现键盘模拟、锁定键盘,锁定鼠标等操作

Delphi 模拟按键的方法 SendMessageA 说明: 调用一个窗口的窗口函数&#xff0c;将一条消息发给那个窗口。除非消息处理完毕&#xff0c;否则该函数不会返回SendMessage所包含4个参数: 1. hwnd 32位的窗口句柄窗口可以是任何类型的屏幕对象&#xff0c;因为Win32能够维护大多数…...

RTK数据的采集方法

采集RTK&#xff08;实时动态定位&#xff09;数据通常涉及使用高精度的GNSS&#xff08;全球导航卫星系统&#xff09;接收器&#xff0c;并通过基站和流动站的配合来实现。本文给出RTK数据采集的基本步骤 文章目录 准备设备设置基站设置流动站数据采集数据存储与处理应用数据…...

Next.js 入门学习

一、引言 在现代 Web 开发领域&#xff0c;Next.js 已成为构建高性能、可扩展且用户体验卓越的 React 应用程序的重要框架。它基于 React 并提供了一系列强大的特性和工具&#xff0c;能够帮助开发者更高效地构建服务器端渲染&#xff08;SSR&#xff09;、静态站点生成&#…...

2024年认证杯SPSSPRO杯数学建模B题(第一阶段)神经外科手术的定位与导航解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 B题 神经外科手术的定位与导航 原题再现&#xff1a; 人的大脑结构非常复杂&#xff0c;内部交织密布着神经和血管&#xff0c;所以在大脑内做手术具有非常高的精细和复杂程度。例如神经外科的肿瘤切除手术或血肿清除手术&#xff0c;通常需要…...

安卓底层相机流的传输方式

这是安卓 相机流的定义 typedef enum {CAM_STREAMING_MODE_CONTINUOUS, /* continous streaming */CAM_STREAMING_MODE_BURST, /* burst streaming */CAM_STREAMING_MODE_BATCH, /* stream frames in batches */CAM_STREAMING_MODE_MAX} cam_streaming_mode_t; 在ca…...

【单链表】(更新中...)

一、 题单 206.反转链表203.移除链表元素 876.链表的中间结点BM8 链表中倒数最后k个结点21.合并两个有序链表 二、题目简介及思路 206.反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 思路简单&#xff0c;但是除了要两个指针进…...

开源堡垒机JumpServer配置教程:使用步骤与配置

开源堡垒机JumpServer配置教程&#xff1a;使用步骤与配置 上一篇文章星哥讲了如何安装JumpServer堡垒机&#xff0c;本篇文章来讲如何配置和使用JumpServer。 安装成功后&#xff0c;通过浏览器访问登录 JumpServer 地址: http://<JumpServer服务器IP地址>:<服务运…...

上门服务小程序开发,打造便捷生活新体验

随着互联网的快速发展&#xff0c;各种上门服务成为了市场的发展趋势&#xff0c;不管是各种外卖、家政、美甲、维修、按摩等等&#xff0c;都可以提供上门服务&#xff0c;人们足不出户就可以满足各种需求&#xff0c;商家也能够获得新的拓展业务渠道&#xff0c;提高整体收益…...

Linux离线包缓存自动化巡检实践

Linux离线包缓存自动化巡检实践这是一篇面向中级 Linux 使用者的技术文章&#xff0c;主题聚焦在离线包缓存&#xff0c;重点讨论无外网安装、本地缓存和依赖完整性。在真实生产环境中&#xff0c;离线包缓存相关问题往往不会以单一错误形式出现&#xff0c;而是混杂在日志、权…...

Git忽略文件失效?一招解决!

场景&#xff1a; 在某次 Git 提交时&#xff0c;忘记在 .gitignore 文件中添加上某个原本应该被忽略的文件夹或者文件&#xff0c;于是后一次的提交时在 .gitignore 加上了这些文件&#xff0c;但是在远程的仓库中这些文件夹、文件却并没有消失。这个属于属于什么问题&#xf…...

【软考高级架构】案例题考前突击19——微服务架构下的服务注册发现与熔断限流机制设计

案例分析题:微服务架构下的服务注册发现与熔断限流机制设计 案例背景 B公司开发了一套大型电商系统,采用Spring Cloud微服务架构实现商品管理、订单管理、支付服务、用户服务、搜索推荐等多个服务模块。系统部署在Kubernetes平台上,采用Eureka作为服务注册中心,Ribbon和F…...

SteamAutoCrack完整指南:一键移除游戏DRM保护

SteamAutoCrack完整指南&#xff1a;一键移除游戏DRM保护 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack SteamAutoCrack是一款专业的开源游戏DRM移除工具&#xff0c;能够自动解除Ste…...

消息平台接入实战:Hermes Agent 实现微信/钉钉日常任务自动化的 4 步配置

1. 微信/钉钉自动化不是“接个API就完事”,而是上下文边界的重新定义 大多数人第一次配置 Hermes Agent 接入微信或钉钉时,会下意识打开官方文档,复制粘贴几行 webhook 配置,跑通一条“收到消息→回复‘你好’”的 demo 就以为大功告成。我试过三次——第一次在测试环境里…...

长期使用聚合API平台,对账单清晰度与费用追溯的满意度反馈

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期使用聚合API平台&#xff0c;对账单清晰度与费用追溯的满意度反馈 作为一名长期负责项目维护的开发者&#xff0c;我所在团队在…...

Pterodactyl-installer数据库配置:MySQL用户权限管理与安全最佳实践

Pterodactyl-installer数据库配置&#xff1a;MySQL用户权限管理与安全最佳实践 【免费下载链接】pterodactyl-installer :bird: Unofficial installation scripts for Pterodactyl Panel 项目地址: https://gitcode.com/gh_mirrors/pt/pterodactyl-installer Pterodact…...

BilibiliDown:B站视频批量下载的终极解决方案

BilibiliDown&#xff1a;B站视频批量下载的终极解决方案 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibi…...

基于Next.js与Shadcn/ui的现代Web仪表盘开发实战指南

1. 项目概述与核心价值 最近在折腾一个开源项目&#xff0c;叫 openclaw-dashboard &#xff0c;是 anis-marrouchi 大佬在 GitHub 上开源的一个仪表盘项目。光看名字&#xff0c;你可能会觉得这又是一个平平无奇的“又一个仪表盘”&#xff0c;但实际深入把玩之后&#x…...

AI 科技日报-2026年5月19日

AI 科技日报 | 2026年5月19日 今日AI领域八大要闻速递 1. 京东宣布AI研发投入增长超200%&#xff0c;"618"全面智能化 京东集团技术委员会主席曹鹏在"618"启动发布会上透露&#xff0c;今年京东体系AI相关研发投入增长将超200%&#xff0c;AI将首次全场…...