LCA(最近公共祖先)算法
参考博客:https://blog.csdn.net/my_sunshine26/article/details/72717112
首先看一下定义,来自于百度百科
LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。

注意:这里某个节点本身也是它的祖先节点。
求最近公共祖先的算法:
1、暴力:每次查询的时间复杂度为O(N)
2、Tarjan(离线)算法:在一次遍历中把所有查询解决,预处理时间复杂度O(nlogn),每次查询时间复杂度O(1),总时间复杂度是O(nlogn+q)
3、倍增算法:利用二分两个节点同时往上走,直到相遇,预处理时间复杂度O(nlogn),每次查询时间复杂度O(logn)
Tarjan(离线)算法
一.Tarjan算法大致实现过程
- 先选择一个节点u为根节点,从根节点开始搜索。(标记u已访问过)
- 遍历该点u的所有儿子节点v,并标记v已访问过。
- 若v还有儿子节点,对v重复ii操作,否则进入下一操作。
- 把v合并到u上(并查集)。
- 把当前的点设为u,遍历与u有询问关系的节点v。
- 如果v在之前已经被访问过,那么u和v的最近公共祖先就是v通过并查集合并后的父亲节点(注意是合并后),即当前的find(v)。
二.Tarjan算法的伪代码
Tarjan(u) //根节点u
{
for each(u,v)
{
Tarjan(v); //v还有儿子节点
join(u,v); //把v合并到u上
vis[v]=; //访问标记
}
for each(u,v) //遍历与u有询问关系的节点v
{
if(vis[v])
{
ans=find(v);
}
}
}
三.Tarjan算法的代码
void Tarjan(int u)
{
vis[u]=;
for(int i=;i<mp[u].size();i++)
{
int v=mp[u][i];
if(vis[v]==)
{
Tarjan(v);
join(u,v);
}
}
for(int i=;i<mp2[u].size();i++)//利用mp2集合来存储查询关系
{
int v=mp2[u][i];
if(vis[v]==)
{
lca[u][v]=find(v);
}
}
}
倍增算法
一、算法铺垫
首先让u和v中较深的一个往上走|depth(u)-depth(v)|步,然后再一起一步步往上走,直到走到同一个节点,就可以在O(depth(u)+depth(v))的时间内求出LCA。
关键在于如何优化向上查找的过程
二.倍增算法的实现过程
分析刚才的算法,两个节点到达同一节点后,不论怎么向上走,达到的显然还是同一节点。利用这一点,我们就能够利用二分搜索求出到达最近公共祖先的最小步数了。
首先我们要进行预处理。对于任意的节点,可以通过fa2[v]=fa[fa[v]]得到其向上走2步到达的顶点,再利用这个信息,又可以通过fa4[v]=fa2[fa2[v]]得到其向上走4步所到的顶点。以此类推,我们可以得到其向上走2^k步所到的顶点fa[v][k],预处理的时间点复杂度为O(nlogn)。
void init()
{
lg[]=;
for(int i=;i<=n;i++)
lg[i]=lg[i-]+(<<(lg[i-]+)==i);//用来求log2(n)
}
void dfs(int f,int fath)
{
deepth[f]=deepth[fath]+;
fa[f][]=fath;
for(int i=;(<<i)<=deepth[f];i++)
fa[f][i]=fa[fa[f][i-]][i-];
for(int i=;i<mp[f].size();i++)
if(mp[f][i]!=fath)
dfs(mp[f][i],f);
}
int lca(int x,int y)
{
if(deepth[x]<deepth[y])
swap(x,y);
while(deepth[x]>deepth[y])
x=fa[x][lg[deepth[x]-deepth[y]]];
if(x==y)
return x;
for(ll k=lg[deepth[x]];k>=;k--)
if(fa[x][k]!=fa[y][k])
x=fa[x][k], y=fa[y][k];
return fa[x][];
}
LCA(最近公共祖先)算法的更多相关文章
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- lca 最近公共祖先
http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- LCA(最近公共祖先)之倍增算法
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...
- LCA最近公共祖先(Tarjan离线算法)
这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...
- 最近公共祖先算法LCA笔记(树上倍增法)
Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了 ...
随机推荐
- mac php项目除了首页全飘not found
1.httpd.conf配置文件中加载了mod_rewrite.so模块2.AllowOverride None 将None改为 All DocumentRoot "/Library/Web ...
- TinkerPop简述
ThinkerPop Apache 顶级项目 概述 TinkerPop是一个面向实时事务处理(OLAP)以及批量.分析型(OLTP)的开源的图计算框架.TinkerPop是一个可以应用于不同图形数据库 ...
- 记换换回收一个js逆向分析
随着现在对数据的重视程度越来越高,现在各大网站都加强了反爬技术,比如本文中js加密 url地址:https://www.huanhuanhuishou.com/gujia/22201.html 需要爬 ...
- Kafka内核理解:消息的收集/消费机制
原文:https://www.cnblogs.com/daochong/p/6425762.html 一.Kafka数据收集机制 Kafka集群中由producer负责数据的产生,并发送到对应的Top ...
- tomcat : 虚拟路径映射
tomcat设置虚拟访问地址和真实路径的映射,方法有几种,这里介绍常用的两种方式: 一.修改server.xml文件: 步骤如下: 1.在tomcat根目录下打开conf文件夹,该文件夹下有个ser ...
- 4 jdngo vue-rotue
. 执行linux命令 与mac命令 git base 3 初始化操作 页面加载完成,发起请求 window.onload
- restful_framework之APIView
一.安装djangorestframework 方式一:pip3 install djangorestframework 方式二:pycharm图形化界面安装 方式三:pycharm命令行下安装(装在 ...
- 在Telnet中用FTP传输文件
如果用 Telnet 传输文件? 在自己的机子上架设FTP服务器,然后登陆远程机后,就可以登录自己的FTP.利用PUT(上传命令),就可以把远程电脑的文件下载下来. 如果出现连接不上FTP,也 ...
- 模块化开发之butterknife 在 library中使用
在Android开发中butterknife是一个很好的对资源初始化的工具,它可以使你的代码简洁通俗易懂,同时配合Android ButterKnife Zelezny插件可以让你写代码的速度提升至少 ...
- SQL Server 各版本安装包分享
已将SQL Server 2005以上各版本的安装包分享到百度云盘,有需要的朋友可以下载进行安装,相关安装教程可以百度搜索.安装遇到难以解决的问题可以留言给我,2016版以上在选择功能的时候建议初学者 ...