LCA 问题 + 模板
Posted 在那遥远的悠穹下
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCA 问题 + 模板相关的知识,希望对你有一定的参考价值。
LCA
LCA 的问题是很经典的,我这一次就来讲解一下 LCA 的求法,就先从一道模板题入手吧
题目
输入格式
第一行包含三个正整数 \\(N,M,S\\) 分别表示树的结点个数、询问的个数和树根结点的序号。
接下来 \\(N-1\\) 行每行包含两个正整数 \\(x, y\\) 表示 \\(x\\) 结点和 \\(y\\) 结点之间有一条直接连接的边(数据保证可以构成树)。
接下来 \\(M\\) 行每行包含两个正整数 \\(a, b\\) 表示询问 \\(a\\) 结点和 \\(b\\) 结点的最近公共祖先。
输出格式
输出包含 \\(M\\) 行,每行包含一个正整数,依次为每一个询问的结果。
说明/提示
对于 \\(30\\%\\) 的数据,\\(N\\leq 10,N \\leq 10\\)。
对于 \\(70\\%\\) 的数据,\\(N\\leq 10000,N \\leq 10000\\)。
对于 \\(100\\%\\) 的数据,\\(N\\leq 500000 , N \\leq 500000\\)
方法
朴素算法
首先,我们想到最暴力的方法,先把整个树 DFS 一下,顺便将每个点的深度记录下来,将要查找的两个点中每次找深度最大的点,然后向上跳一格,最后两个点一定会相遇,相遇的点就一定是他们的 LCA 。
下面是 DFS 的代码
void dfs(int u,int fa){ // fa 为父亲节点,u 为当前节点, dep 为节点深度
f[u] = fa;
dep[u] = dep[fa] + 1; // 因为是 DFS ,每个节点是从它的父亲来的,父亲与儿子的深度相差 1
for(int i=head[u];i;i = nex[i]){ // 链式前向星
int v = to[i];
if(v != fa)
dfs(v,u);
}
}
以上是关于LCA 问题 + 模板的主要内容,如果未能解决你的问题,请参考以下文章