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

LCA(最近公共祖先)

LCA(Least Common Ancestors),即最近公共祖先,例如求两个节点u, v两个节点的最近的共同祖先我们可以用暴力、倍增、ST等方法解决

暴力

暴力法求解一对节点u和v的LCA时时间复杂度是O(n)的,所以当查询多对节点的LCA时,暴力算法的时间复杂度往往不满足要求。
暴力法就是通过不断地将深度较深的点往上求父节点,直到两个点的父节点重合时,即可得到LCA。

倍增

倍增法其实就是在暴力的基础上每一步尽可能跳的多一些,假设我们要求解lca(u,v),暴力的想法是我们始终将深度较深的往上跳跃一步,直到u,v的深度第一次相等时,此时该节点就是lca(u,v),但是这样做的话,时间复杂度是O(n)的,当有多组查询时,就容易超时。

倍增的原理是每一次尽可能地多跳一些步数,而不是一步一步往上跳,我们便可以选择跳跃2^j步进行尝试。

例题(倍增):

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

题目描述

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

输入格式

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

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

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

输出格式

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

思路:

设树中u、v两结点的最近公共祖先为lca(u,v)。用dfs求出他们的深度和父亲节点再在lca中倍增去不断(父亲不相等的话)的跳(2^j)

代码:

#include<bits/stdc++.h> using namespace std; int depth[500005] , father[500005][25] , n , m , s , x , y , a , b; vector<int> g[500005]; void dfs(int u , int fa){ father[u][0] = fa; for(int i = 1;i <= 20;i++){ father[u][i] = father[father[u][i - 1]][i - 1]; } depth[u] = depth[fa] + 1; for(int i = 0;i < g[u].size();i++){ int v = g[u][i]; if(v == fa){ continue; } dfs(v , u); } } int lca(int u , int v){ if(depth[u] < depth[v]){ swap(u , v); } for(int i = 20;i >= 0;i--){ if((depth[u] - depth[v]) >= (1 << i)){ u = father[u][i]; } } if(u == v) return u; for(int i = 20;i >= 0;i--){ if(father[u][i] != father[v][i]){ u = father[u][i]; v = father[v][i]; } } return father[u][0]; } int main(){ scanf("%d%d%d" , & n , &m , &s); for(int i = 1;i < n;i++){ scanf("%d%d" , &x , &y); g[x].push_back(y); g[y].push_back(x); } dfs(s , 0); for(int i = 1;i <= m;i++){ scanf("%d%d" , &a , &b); printf("%d\n" , lca(a , b)); } return 0; }
http://www.jsqmd.com/news/762312/

相关文章:

  • 避坑指南:STM32 CORDIC计算浮点sin/cos时,角度转换与数据溢出的那些事儿
  • 从“价值对齐”到“责任内化”:以字基网络伦理,观照DeepSeek V4的成人之路
  • 黑客技术零基础入门到精通教程(非常详细),附完整学习路线及高薪指南!
  • 瑞萨RL78 DataFlash读写避坑全攻略:从PFDL库安装到防程序卡死的实战经验
  • 医学视觉思维链:AI诊断推理能力突破
  • YOLO-Master动态计算目标检测框架解析
  • 工业物联网数据采集革命:Apache PLC4X一站式跨平台解决方案深度解析
  • 别再蒙圈了!手把手教你用CANoe和示波器实测CAN/CAN FD波特率(附配置截图)
  • PHP内存占用骤降62%的实战方案,基于PHP 8.9新GC阈值算法(含压测对比数据+可复用配置模板)
  • 从仿真到实战:基于openclaw 101在快马平台搭建零件分拣系统原型
  • 别再为JSON解析报错头疼了!Jackson 2.x的JsonReadFeature帮你搞定那些‘不标准’的数据
  • 家庭财务管理系统【答辩文档】
  • 提升开发效率:用快马平台打造智能ccswitch代理管理工具
  • AI驱动的3D室内场景生成技术SPATIALGEN解析
  • TiDAR架构:扩散与自回归模型的深度并行融合
  • SHAMISA:自监督无参考图像质量评估技术解析
  • PHP类型校验的“瑞士军刀”:1个trait搞定DTO验证、API入参过滤、数据库写入前强制类型归一化(含GitHub Star 2.4k开源组件深度解析)
  • 环境配置与基础教程:26届秋招避坑:熟悉 PyTorch 的 Profiler 性能瓶颈分析工具,精准找出 YOLO 训练过程的耗时热点
  • 基于MCP协议与Loom GraphQL API,构建AI视频内容管理自动化工作流
  • 手把手教你用示波器抓取LPDDR4的Read时序:从tDQSCK到tDQSQ的实战测量指南
  • 萌新游戏开发记录——AI开发和游戏框架学习(三)
  • 从SystemVerilog的Mailbox到UVM TLM:手把手教你重构一个可重用的验证组件通信层
  • 新手避坑指南:STM32F103C8T6自制板烧录失败,我踩过的那些硬件坑(附解决方案)
  • 开源提示词库:工程化AI协作,提升LLM输出质量与效率
  • m4s-converter:B站视频缓存格式的工程化转换解决方案
  • 别再盲目开opcache.jit=1235!PHP 8.9 JIT真实场景吞吐量拐点分析——37组AB压测数据告诉你何时该关
  • Python 开发者如何通过 OpenAI 兼容协议快速接入 Taotoken 多模型服务
  • 视频事件预测:基于事件链的视觉注意力增强方法
  • linux实现双网卡负载均衡 ——企业高可用网络方案与实践
  • 实战应用:基于快马平台构建可部署的智能故障诊断宏智树系统