Tarjan求LCA

浅谈Tarjan算法求LCA Tarjan是一个很厉害的人,不少算法(包括一些数据结构比如splay)都是他发明的…Tarjan求LCA是利用并查集的思想进行操作的首先我们有如下的思路void Tarjan(int u){ fa[u]=u; for(register int i=head[u];i;i=line[i].nxt){ int v=line[i].to; if(v!=fa 阅读详情

LCA

树上最近公共祖先的简称。可以是父节点,也可以是自己。

算法思路

这种求LCA的算法比较常用,而且是离线的。需要用到并查集数据类型。算法基本流程为
1.访问点u。
2.标记访问,并认自己为爹。
3.遍历点u的所有儿子。如果儿子还有儿子,则再访问儿子的所有儿子。
4.查询所有与该点有关的询问。若另一个点已被访问,找到对方的爹,就是lca。
由此可以看出此算法是离线的,可以一次性处理完所有询问,所以其时间复杂度也比较小。

相关复杂度

时间复杂度为o(m+n)

代码

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,q,tol,tolq,p;
int fa[5005];
struct edge{
 int nxt;
 int to;
 int lca;
}e[5005];//结构体存边 
struct edge qs[5005];
int hd[5005],hdq[5005];
bool vis[5005];
void add(int u,int v)//u to v,end at 0
{
 tol++;
 e[tol].nxt=hd[u];
 e[tol].to=v;
 hd[u]=tol;
}
void addq(int u,int v)//u to v,end at 0
{
 tolq++;
 qs[tolq].nxt=hdq[u];
 qs[tolq].to=v;
 hdq[u]=tolq;
}
int getfa(int t)//找爹函数
{
 return fa[t]==t?t:getfa(fa[t]);
} 
void tarjan(int u)
{
 vis[u]=1;
 fa[u]=u;//注意顺序 
 for(int i=hd[u];i;i=e[i].nxt)
 {
  int v=e[i].to;
  if(!vis[v])
  {
   tarjan(v);
   fa[v]=u;
  }
 }
 for(int i=hdq[u];i;i=qs[i].nxt)
 {
  int v=qs[i].to;
  if(!qs[i].lca&&vis[v])
  {
   qs[i].lca=getfa(v);
   if(i%2) qs[i+1].lca=qs[i].lca;
   else qs[i-1].lca=qs[i].lca; 
  }
 }
}
int main()
{
 scanf("%d%d%d",&n,&m,&p);//需输入根节点 
 for(int i=1;i<=m;i++)
 {
  int x,y;
  scanf("%d%d",&x,&y);
  add(x,y);
  add(y,x);
 }
 scanf("%d",&q);
 for(int i=1;i<=q;i++)
 {
  int x,y;
  scanf("%d%d",&x,&y);
  addq(x,y);
  addq(y,x);
 }
 tarjan(p);
 for(int i=1;i<=q;i++)
 printf("%d\n",qs[i*2].lca);
 return 0;
} 
Tarjan 的 LCA 算法 c++写的Tarjan 的 LCA 算法,最近公共祖先算法,可供算法学习参考 立即下载

相关推荐

FINCH-Clustering:FINCH聚类算法的源代码

第一整数邻居聚类层次结构(FINCH)算法 该存储库包含用于建议的FINCH聚类算法的Python和Matlab代码,在我们的《使用第一个邻域关系进行有效无参数聚类CVPR 2019口头。 @inproceedings{finch, author = {M. Saquib Sarfraz, Vivek Sharma and Rainer Stiefelhagen}, title = {Efficient Parameter-free Clustering Using First Neighbor Relations}, booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, pages = {89

【算法学习03】Tarjan&LCA

在有根树中,找出某两个结点u和v最近的公共祖先。一般有两种方法:树上倍增大跳求LCA和Tarjan离线算法求LCA,本篇主要描述Tarjan离线算法求LCA。

m0_46121643的博客 1345

[HCTF 2018]WarmUp 1学习记录

#[HCTF 2018]WarmUp 1学习笔记 最近做了做ctf,觉得真的很有趣,后悔当初没早点做,不过之前的学习也让我得到了不少经验基础,废话不多说,这次ctf虽然基本上靠了网上的大佬们(因为比较菜),但自己也做了些思考,应该对新手也比较友好吧。 ##1 首先怎么找源码,我承认我确实刚开始不知道在哪找,不过也很快找到了,相信也会有部分新手和我差不多吧 然后下面控制台会有个temp0,然后直接回车 后面我就受到启发,直接在链接后面加上source.php,进行页面跳转,然后就可以开始PHP代码审计了。

weixin_45869407的博客 684

详解使用 Tarjan 求 LCA 问题(图解)

LCA问题有多种求法,例如倍增,Tarjan。 本篇博文讲解如何使用Tarjan求LCA。 如果你还不知道什么是LCA,没关系,本文会详细解释。 在本文中,因为我懒为方便理解,使用二叉树进行示范。 LCA是什么,能吃吗? LCA是树上最近公共祖先问题。 最近公共祖先就是树上有两个结点,找一个结点,是他们的公共祖先,并且离他们两个结点最近。 例如这是一棵树: 树上 4,7 两个...

weixin_34315485的博客 1395

解决Unity与3DMax模型单位与中心点偏差的完整指南

本文详细解析了Unity与3DMax模型导入时常见的单位与中心点偏差问题,提供了从3DMax单位设置、FBX导出到Unity接收调整的完整解决方案。通过实战案例和高效工作流建议,帮助开发者实现unity与3dmax的单位统一,避免尺寸错误和轴心偏移,提升3D资源导入效率。

weixin_29015899的博客 286

2019年7月28日解决战网BLZBNTBNA00000005BLZBNTBNA00000006BLZBNTBTS0000005DBLZBNTBTS0000004A 007D0 008A4 00840

Blizzard—Battle.net—2019年7月28解决战网BLZBNTBNA00000005BLZBNTBNA00000006BLZBNTBTS0000005DBLZBNTBTS0000004A 007D0 008A4 008402019年7月28日再次更新写在前面■■■ 排查网路问题 ■■■■■■ 排查电脑自身问题 ■■■■尝试重置internet设置■网络的设置和防火墙规则■如果还是不...

MCGC高质人类协作会-MCG贴吧 3万+

Tarjan 算法解决 LCA 问题

算法

实践求真知 979

stata:stata软件教程(人大十八讲)(1) 第一章 stata入门

第一章 stata入门1.1 安装1.2 启用和退出1.3 打开和查看数据1.4 寻求帮助与网络资源1.5 命令示例1.6 几个环境设置1.7 复习与练习1.8 附录 注:教材为:Stata 统计分析教程 stata软件教程(人大十八讲) 中国人民大学出版社 陈传波 1.1 安装 1.2 启用和退出 1.3 打开和查看数据 1.4 寻求帮助与网络资源 1.5 命令示例 1.6 几个环境设置 1.7 复习与练习 1.8 附录 ...

qq_47805483的博客 1万+

trajan算法求lca 超级详细配图讲解

关于离线算法 (下面内容可以略过。) 离线算法其实就是将多个询问一次性解决。离线算法往往是与在线算法相对的。例如求LCA的算法中,树上倍增属于在线算法,在对树进行O(n)O(n)O(n)预处理后,每个询问用O(log2n)O(log_2n)O(log2​n)复杂度回答。而离线的Tarjan算法则是用O(n+q)O(n+q)O(n+q)时间将询问一次性全部回答。 详解 下面是一棵树,我们将以这棵树为例子讲解Tarjan算法,其中0号点为根。 假设对于这棵树的询问有4个,分别询问: LCA(2,8)LCA(2

m0_50219534的博客 1261

切比雪夫(最小区域法)直线拟合算法

切比雪夫,最小区域法直线拟合

闪电彬彬的博客 3962

45 - Android系统源码-crosvm 实战:基于 KVM 的 Rust 安全虚拟机监控器核心技术

摘要:crosvm 是 Google 开发的基于 KVM 的轻量级虚拟机监控器(VMM),采用 Rust 语言编写,专为 ChromeOS 和 Android 设计。其核心特点包括: 安全架构:通过 Rust 的内存安全特性和多进程隔离(每个设备运行在独立沙箱进程)大幅降低攻击面 性能优化:基于 KVM 的硬件虚拟化支持,结合异步 I/O (io_uring/epoll) 实现高效设备模拟 模块化设计:清晰的 trait 抽象层(Hypervisor/Vm/Vcpu)支持跨平台扩展 Android 集成

保持专注,保持热爱 226

Tarjan—离线求LCA

针对有询问的题目,在线做法为读入一个询问立刻给出输出;离线做法为读入所有询问后再给出输出。

weixin_62224014的博客 950

SXU-软件项目管理-朱少民-第九章 项目监控与控制 第十章 项目收尾 附相关习题

软件项目管理-朱少民-第九章 项目监控与控制 附相关习题

weixin_63597914的博客 1488

Tarjan算法离线求LCA

最近学习了Tarjan离线求LCA,写篇博客记录一下: 先贴出来:学习博客(讲的很好很详细~) 1.定义: LCA(Lowest Common Ancestor)最近公共祖先,即树上两个点最新的公共祖先节点 比如:lca(1,4)=1; lca(4,5)=3; lca(2,3)=1; 2.伪码: Tarjan(u){ for each(u,v){//遍历每一个u的...

m0_37579232的博客 326

【AI工具】Browser use搭建及使用的保姆级教程:让AI帮你自动操作浏览器

【AI工具】Browser use搭建及使用的保姆级教程:让AI帮你自动操作浏览器

funfan的博客 2535

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Tarjan求LCA(最近公共祖先)

在有根树中,找出某两个结点u和v最近的公共祖先。一般有两种方法:树上倍增大跳求LCA和Tarjan离线算法求LCA,本篇主要描述Tarjan离线算法求LCA。5、寻找与当前节点u有关的查询,判断所查询的除了u以外的另一节点u’是否已访问。6、若u’已经被访问过,则u和u’的LCA就是u’已经被合并到的节点。2、遍历当前节点u的所有子节点(邻居节点)v,并置u节点为已访问。1、任选一个节点root作为根节点,从根节点开始遍历。3、若v还有子节点,则继续递归其子节点。4、并查集合并v到u上面。

2302_81590667的博客 740

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Tarjan入门⑤离线求LCA

前言: md,感觉LCA上我的学习顺序正好反过来了。先学的ST+欧拉序,后学的倍增。最后才学的Tarjan求LCA。 这个算法唯一不足就是离线的,但是一大好处就是实现起来超级简单。理解起来也很简单. 本质上就是一个dfs。 我们对每一个点开一个vector存询问。对于任意两个点u,vu,vu,v。dfs的时候要么先遍历u再遍历v.要么反之。所以我们需要对u,vu,vu,v都插入询问。 当访问到vvv时,若uuu已经被访问了,那么LCA(u,v)LCA(u,v)LCA(u,v)这个点一定是被访问且未结束访问的

qq_35577488的博客 244

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

tarjan离线、倍增在线求LCA

一、何为在线与离线? 在线算法:指它可以以序列化的方式一个个的处理输入,也就是说在开始时并不需要已经知道所有的输入。 离线算法:在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果。 例如,选择排序在排序前就需要知道所有待排序元素,然而插入排序就不必。 因为在线算法并不知道整个...

llyzznn的博客 278

Tarjan离线求LCA模板

Tarjan 算法求 LCA 的时间复杂度为 O(n+q) ,是一种离线算法,要用到并查集。 ps:时间复杂度其实还需要考虑并查集操作的时间复杂度 ,但是由于在多数情况下,路径压缩并查集的单次操作复杂度可以看做 O(1),所以直接近似为 O(n+q) 。 const int MAXN = ;//最大点数 pair&lt;int,int&gt; P[205];//存询问边 int lca...

vocaloid01的博客 740

浅谈Tarjan——5(用Tarjan求LCA)

Tarjan算法不仅可以用来缩点,还可以用来求LCA。先介绍一下LCA,LCA(least common ancestors),是最近公共祖先的英文。指的是在一棵树中,点u和点v的最近的祖先。 如图,以黄点为树根:紫点和黑点的最近公共祖先就是绿点,白点和橙点的最近公共祖先就是橙点,灰点和蓝点的最近公共祖先是黄点。简而言之,LCA就是点u和v的父亲的父亲的父亲……第一个相交的父亲。LCA的算法有很多

stevensonson的博客 455

tarjan,树剖,倍增求lca

1.tarjan求lca 思想: void tarjan(int u,int f){ for(int i=---){//枚举边 if(v==f) continue; dfs(v); //继续搜 unionn(v);//合并 vis[v]=1; //标记 } for(i...

weixin_30697239的博客 116

1556:Dis——Tarjan求LCA、倍增求LCA

【题目描述】给出 n 个点的一棵树,多次询问两点之间的最短距离。注意:边是双向的。【输入】第一行为两个整数 n 和 m。n 表示点数,m 表示询问次数;下来 n−1 行,每行三个整数 x,y,k,表示点 x 和点 y 之间存在一条边长度为 k;再接下来 m 行,每行两个整数 x,y,表示询问点 x 到点 y 的最短距离。【输出】输出 m 行。对于每次询问,输出一行。【输入样例】2 21 2 1001 22 1【输出样例】100100【提示】

与其邻渊羡渔,不如退而结网 911

tarjan求LCA

tarjan求LCA//poj 1986 #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> using namespace std;const size_t MAXN = 100005, MAXQ = 100005;int N, Q, M;struct Edge { int u, v, n

nerium_indicum的博客 297

离线tarjan求lca的学习和所有习题

离线tarjantarjantarjan求lcalcalca的学习和所有习题 前言: 离线tarjantarjantarjan,跟tarjantarjantarjan求图的连通性没有关系,因为tarjantarjantarjan这个人tqltqltql,发明了各种数据结构和算法,所以用他的名字命名的算法太多了。 1.所谓离线就是给定若干个询问,不是每次给定一个询问就给出答案,而是在给定所有询问之后一次性将所有询问解决掉,然后每个O(1)O(1)O(1)的输出答案。 2.所谓离线tarjantarjantar

Harris-H的博客 687

Tarjan算法求LCA正确性大致证明

每次只要将一个子树遍历完,就将其合并到其直接父亲节点上,因为后面的几个分叉出的子树中的点,与在以遍历完的子树中的点的LCA一定是它们的直接父亲节点(图中是节点1)。但是,这样会增加时间复杂度,因为如果先遍历,后更新,所有在以当前节点为根的子树中的点都会被算2次,一次在当前节点,一次在询问中的另一个节点。对于所有在以2号点为根的子树中的点,如果要求它们与一个在以3至6号点为根的子树中的点的LCA,那么结果都一定是1,因为这两个点都和2至6节点一样从1号节点开始分在了两个不同的子树中。

shenshi6666的博客 379
上一篇: 并查集
下一篇: Tarjan找强连通分量
Edith_Finch
博客等级 码龄9年 2粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值