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

C++中的LCA(最近公共祖先)详解

C++中的LCA(最近公共祖先)详解

LCA(Lowest Common Ancestor) 指树结构中两个节点的最近公共祖先节点(深度最大的共同祖先)。常用于解决树上的路径查询、距离计算等问题。

核心算法(倍增法)

  1. 预处理(DFS)
    • 记录每个节点的深度 depth[]
    • 构建倍增表 parent[u][k],表示节点 u 向上跳 2k2^k2k 步的祖先。
  2. 查询步骤
    • 对齐深度:将深度较大的节点上跳到与另一节点同深度;
    • 同步上跳:从最大步长 kkk 开始尝试(k=log⁡2(树深度)k = \log_2(\text{树深度})k=log2(树深度)),若祖先不同则同步上跳;
    • 返回结果:最终父节点即为LCA。

C++代码实现

#include <vector>
#include <cmath>
#define MAXN 100000  // 最大节点数
using namespace std;vector<int> tree[MAXN];    // 邻接表存树
int depth[MAXN];           // 节点深度
int parent[MAXN][20];      // 倍增表:parent[u][k] = u的2^k级祖先// 预处理DFS(初始化深度及倍增表)
void dfs(int u, int p) {depth[u] = depth[p] + 1;parent[u][0] = p;for (int k = 1; k < 20; k++) {  // 20足够覆盖2^20深度的树if (parent[u][k-1] != -1) {parent[u][k] = parent[parent[u][k-1]][k-1];}}for (int v : tree[u]) {if (v == p) continue;dfs(v, u);}
}// LCA查询函数
int lca(int u, int v) {// 步骤1: 对齐深度if (depth[u] < depth[v]) swap(u, v);int diff = depth[u] - depth[v];for (int k = 0; diff; k++) {if (diff & 1) u = parent[u][k];diff >>= 1;}// 步骤2: 同步上跳if (u == v) return u;  // v是u的祖先for (int k = 19; k >= 0; k--) {if (parent[u][k] != parent[v][k]) {u = parent[u][k];v = parent[v][k];}}return parent[u][0];  // 返回最终父节点
}// 初始化调用
int main() {memset(parent, -1, sizeof(parent));depth[0] = -1;  // 假设根节点为1,其父节点0深度为-1dfs(1, 0);       // 从根节点1开始DFS// 查询示例: lca(4, 5)
}

关键点说明

  1. 时间复杂度
    • 预处理:O(N×log⁡2N)O(N\times\log_2 N)O(N×log2N)
    • 单次查询:O(log⁡2N)O(\log_2 N)O(log2N)
  2. 适用场景
    • 静态树结构(无动态修改)
    • 频繁查询场景(如竞赛题目)
  3. 空间优化
    • 倍增表大小:parent[MAXN][log2(MAXN)]
    • 实际中取 kmax⁡=20k_{\max} = 20kmax=20 可覆盖 10610^6106 节点

其他解法对比

方法时间复杂度特点
倍增法预处理O(N×log⁡2N)O(N\times\log_2 N)O(N×log2N),查询O(log⁡2N)O(\log_2 N)O(log2N)通用性强,易实现
TarjanO(N+Qα)O(N+Q\alpha)O(N+Qα)离线算法,理论效率最优
树链剖分预处理O(N)O(N)O(N),查询O(log⁡2N)O(\log_2 N)O(log2N)支持动态树修改
http://www.dtcms.com/a/533323.html

相关文章:

  • 防止过拟合相关技术
  • 重庆网站建设哪里比较好呢遵义市做网站的电话
  • 【补题】The 3rd Universal Cup. Stage 15: Chengdu B. Athlete Welcome Ceremony
  • SZU大学物理1实验报告|薄透镜
  • 深入理解sigaction函数:Linux信号处理机制与使用指南
  • 网站设计公司哪家专业在线种子资源网
  • 便宜做网站如何免费做网站赚钱
  • 4 Initialization and Training(初始化和训练)
  • 简易银行系统->多线程高并发
  • 【系统分析师】高分论文:论基于构件的软件开发(气象灾害影响评估系统)
  • 【java面向对象进阶】------多态综合案例
  • 做一个内容网站多少钱wordpress调用导航
  • 惠州网站开发公司电话个人兴趣图片集网站建设
  • C++ list 类的使用
  • 怎么利用QQ空间给网站做排名没有专项备案的网站
  • 显示官网字样的网站怎么做wordpress 多站点主题
  • 如何建设一个新的网站快手推广软件免费版
  • 国内十大搜索引擎网站安徽网络关键词优化
  • 【Linux】定制Linux系统
  • 个人网站备案取消网站建设管理分工
  • 企业网站建设的趋势手机网站建设的整体流程图
  • 松原做招聘的网站有哪些系统优化的意义
  • 业务流程图 —— 讲清“谁做了什么事”
  • 天津网站建设咨询杭州景观设计公司排行
  • 10.5 小项目:如何用 JavaScript 实现一个高效的时间+Token过期容器?
  • 网站备案帐号找回密码免费友链平台
  • Every other Cycle Command Input(隔循环命令输入)
  • 更换docker默认镜像仓库地址方法
  • 福建省交通建设质量安全监督局网站软文写作技巧
  • 装饰公司营销型网站设计网站图片等比缩小