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

题目描述:

读入一棵以1为根的树,q次询问,每次给定x和y,问x和y的最近公共祖先是哪一个节点。

树的读入格式:n-1行每行两个整数x、y,表示一条连接x和y的边,保证输入的图形成一棵树。

输入格式:

第一行两个整数为n和q,之后按题目描述读入一棵树。

再之后q行,每行两个整数x和y,表示一组询问。

输出格式:

q行,每行1个整数表示答案。

样例输入1:

10 5
2 1
2 3
2 4
5 4
3 6
7 6
8 1
1 9
1 10
9 8
3 1
7 4
6 2
10 7

样例输出1:

1
1
2
2
1

\(1\le n,q\le 10^5\)

设 \(fa_{x,i}\) 表示 \(x\) 的 \(2^i\) 级祖先,由二进制可知正确性(循环时i从大到小,详见代码),可以 \(O(n\log n)\)预处理,\(O(\log n)\)查询。

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
vector<int>g[N];
int fa[N][21],n,q,dep[N];
void dfs(int u,int deep,int fat) {
fa[u][0]=fat;
dep[u]=deep;
for(int i=0; i<g[u].size(); ++i) {
int v=g[u][i];
if(v==fat)continue;
dfs(v,deep+1,u);
}
}
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() {
scanf("%d%d",&n,&q);
for(int i=1,x,y;i<n;++i)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,1,1);
for(int i=1; i<=20; ++i) {
for(int j=1; j<=n; ++j) {
fa[j][i]=fa[fa[j][i-1]][i-1];
}
}
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}

倍增求LCA(最近公共祖先)的更多相关文章

  1. 求LCA最近公共祖先的在线倍增算法模板_C++

    倍增求 LCA 是在线的,而且比 ST 好写多了,理解起来比 ST 和 Tarjan 都容易,于是就自行脑补吧,代码写得容易看懂 关键理解 f[i][j] 表示 i 号节点的第 2j 个父亲,也就是往 ...

  2. 求LCA最近公共祖先的在线ST算法_C++

    ST算法是求最近公共祖先的一种 在线 算法,基于RMQ算法,本代码用双链树存树 预处理的时间复杂度是 O(nlog2n)   查询时间是 O(1) 的 另附上离线算法 Tarjan 的链接: http ...

  3. 求LCA最近公共祖先的离线Tarjan算法_C++

    这个Tarjan算法是求LCA的算法,不是那个强连通图的 它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数 它的优点是比在线算法好写很多 不过有些题目是强制在线的,此类离线算法 ...

  4. cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!

    2450. 距离 ★★   输入文件:distance.in   输出文件:distance.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...

  5. 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))

    倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...

  6. 树上倍增求LCA(最近公共祖先)

    前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...

  7. [算法]树上倍增求LCA

    LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...

  8. lca最近公共祖先(模板)

    洛谷上的lca模板题--传送门 学了求lca的tarjan算法(离线),在洛谷上做模板题,结果后三个点超时. 又把询问改成链式前向星,才ok. 这个博客,tarjan分析的很详细. 附代码-- #in ...

  9. 【倍增】洛谷P3379 倍增求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  10. D5 LCA 最近公共祖先

    第一题: POJ 1330 Nearest Common Ancestors POJ 1330 这个题可不是以1为根节点,不看题就会一直wa呀: 加一个找根节点的措施: #include<alg ...

随机推荐

  1. Linux CentOS7 VMware 文件和目录权限chmod、更改所有者和所属组chown、umask、隐藏权限lsattr/chattr

    一.文件和目录权限chmod u User,即文件或目录的拥有者:g Group,即文件或目录的所属群组:o Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围:a All,即全部 ...

  2. DatePicker和DataPickerDialog以及AutoCompleteTextView的基本使用方法

    1.DatePicker和DatePickerDialog的基本使用方法: main.xml: <?xml version="1.0" encoding="utf- ...

  3. IntelliJ如何设置自动导包

    idea 关于自动导包的设置 标签: idea 2016-09-30 18:10 400人阅读 评论(0) 收藏 举报 本文章已收录于: .embody{ padding:10px 10px 10px ...

  4. 在 Rolling Update 中使用 Health Check【转】

    上一节讨论了 Health Check 在 Scale Up 中的应用,Health Check 另一个重要的应用场景是 Rolling Update.试想一下下面的情况: 现有一个正常运行的多副本应 ...

  5. An attempt was made to call the method com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder; but it does not exist. Its class, com.google.gson.GsonBuilder, is available from the foll

    SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/G:/sharp/repo ...

  6. 最近学习总结 Nodejs express 获取url参数,post参数的三种方式

    express获取参数有三种方法:官网实例: Checks route params (req.params), ex: /user/:id Checks query string params (r ...

  7. sql 经纬度范围检索(谷歌方案)

    SELECT id, ( * acos ( //公里: 6371 英里: 3959 cos ( radians(78.3232) ) * cos( radians( 数据库纬度字段) ) * cos( ...

  8. 使用gulp 进行ES6开发

    使用gulp 进行ES6开发 一.新建项目 项目结构如下: /app -- /js -- /css /dist -- /js -- /css -- index.html gulpfile.js 我们的 ...

  9. 自己写个tween

    public Vector3 begin,end;//起始终止坐标 public float BtoE_time;//用时 float timer,lerp;//计时器和进度值 void Update ...

  10. 打开exe并传参

    shellexecute(Application.Handle,'open',PWideChar('E:\控件\TMS.Scripter.Studio.Pro..6.0.2.0.Delphi.BCB. ...