首页 > 其他分享 >「学习笔记」tarjan求最近公共祖先

「学习笔记」tarjan求最近公共祖先

时间:2023-04-30 09:13:14浏览次数:37  
标签:tarjan 祖先 查集 棵子 笔记 int 节点

Tarjan 算法是一种 离线算法,需要使用并查集记录某个结点的祖先结点。
并没有传说中的那么快。

过程

将询问都记录下来,将它们建成正向边和反向边。
在 dfs 的过程中,给走过的节点打上标记,同时维护并查集,这里利用了回溯的思想,如果 \(u\) 节点的这棵子树没搜完,那么 fa[u] = u;,搜完后,在更新并查集。
我们假设查询 \(u\) 和 \(v\) 的最近公共祖先,搜到节点 \(u\),如果另一个节点 \(v\) 已经被搜到过了,那么 \(v\) 点的并查集祖先就是 \(u\) 和 \(v\) 的最近公共祖先。

如果第一次查询 \(v\) 点时,发现 \(v\) 点已经被搜到了,说明 \(u\) 和 \(v\) 点在同一棵子树中,并且这个子树是所有包括了 \(u\) 点和 \(v\) 点的子树中 siz 最小的,这棵子树的根也是在所有符合条件的子树的根中离 \(u\) 和 \(v\) 最近的,即这棵子树的根就是 \(u\) 和 \(v\) 的最近公共祖先,而 \(v\) 的并查集祖先就是这个根节点。

代码

结构体记录询问

int cnt = 1;

struct query {
	int v, lca, nxt;
} q[N << 1];

记录询问、初始化

for (int i = 1, x, y; i <= m; ++ i) {
	scanf("%d%d", &x, &y);
	add_query(x, y);
	add_query(y, x);
}
for (int i = 1; i <= n; ++ i) {
	fa[i] = i;
}

tarjan、并查集

void tarjan(int u) {
	fa[u] = u;
	vis[u] = 1;
	for (int v : son[u]) {
		if (!vis[v]) {
			tarjan(v);
			fa[v] = u;
		}
	}
	int v;
	for (int i = h[u]; i; i = q[i].nxt) {
		if (vis[v = q[i].v]) {
			q[i].lca = q[i ^ 1].lca = find(v);
		}
	}
}

fa[u] = u; 是为了保证在 \(u\) 这棵子树没有搜完的情况下,让它子树里的节点的并查集找祖先时找到的是它。

标签:tarjan,祖先,查集,棵子,笔记,int,节点
From: https://www.cnblogs.com/yifan0305/p/17364892.html

相关文章

  • Docker实战笔记4-安装jenkins
    文章目录拉取jenkins镜像排查问题验证结果总结拉取jenkins镜像在官方镜像仓库查询jenkins镜像https://hub.docker.com/r/jenkins/jenkins拉取镜像dockerpulljenkins/jenkins结果如下:zhao@sh-zhao~%dockerpulljenkins/jenkins:latestlatest:Pullingfromjenkins/j......
  • 构建之法阅读笔记1
      第一阶段读了构建之法的1-6章,感觉自己收获比较大、印象深刻的有如下几处:    第一个是初级软件工程师如何去成长的问题。1.要积累软件开发相关知识,提升技术技能。    技术有很多种,你不需要做到全会,但至少你要对其中一种做到熟练掌握,每一个都懂一点,每一个又都......
  • 《代码大全2》阅读笔记05
    在阅读这十一章之前,我曾经遇到过一个问题。在编写代码时,我往往会尝试使用最新的技术和最酷的功能,而忽略了代码的可读性和可维护性。我觉得,只要我的代码能够正常工作,就没有什么问题。然而,在阅读这一章之后,我意识到这种想法是错误的。书中介绍了许多关于代码可读性和可维护性的最佳......
  • Vim学习笔记
     在Linux终端命令行输入gvim&打开GVIMVim打开文件终端输入:gvim***或gvim***&使用Vim独立打开文件vim***在终端显示文件&:表示当前的这个进程打开,但是它还不影响你接下来在terminal上面敲一些其他的一些命令Vim实现比较文件代码终端输入:gvimdifffileafileb或者......
  • DVT_eclipse学习笔记1
    常用方法1.自动补全快捷方式:alt+/(可以多次按这个“/”选择补全的东西)自动补全有时候会包含许多提案,分为几类:第一个是你可以在范围内访问的内容(信号、变量、方法等,取决于所包含的范围)alt+/第二个用于代码模板alt+/+/第三个是其他的东西,例如模块实例alt+/+/+/2.快速修......
  • 中国剩余定理(CRT)学习笔记
    约定\(A\perpB\)表示\(\gcd(A,B)=1\)。\(A\midB\)表示\(B\equiv0\pmod{A}(A\neq0)\)。引入考虑以下这道题:有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何?——《孫子算經》也就是说,求出下列关于\(x\)方程组的最小整数解:\[\begin{cases}x\equi......
  • SpringCloud学习笔记
    Eureka基本知识Eureka主要学习的是微服务的一些基本概念之类的,至于具体的操作其实都是在配置appolication.yml文件了,多看文档以及自己写过的demo就懂了。Eureka在微服务中承担的角色有三个,一个是注册中心server,一个是服务供给方porvider,以及接受用户请求的consumer,如果从启动类......
  • 构建之法阅读笔记02
    《构建之法》是一本关于软件架构设计的经典著作,作者是美国软件工程师、架构师和教育家Christopher Alexander。这本书提出了一种全新的软件架构设计方法——模式语言法,通过模式语言法,可以帮助软件架构师和设计师更好地理解软件系统的结构和设计,提高软件的可维护性和可扩展性。本......
  • Django笔记三十三之缓存操作
    本文首发于公众号:Hunter后端原文链接:Django笔记三十三之缓存操作这一节介绍一下如何在Django中使用redis做缓存操作。在Django中可以有很多种方式做缓存,比如数据库,比如服务器文件,或者内存,这里介绍用的比较多的使用redis作为缓存。这篇笔记主要内容如下:依赖安装se......
  • 笔记:《语义化版本》速记口令
    笔记:《语义化版本》速记口令FastAdmin#版本管理语义化版本版本号管理是项目管理中的重中之重,如果版本号管理混乱,会导致项目冲突,引发项目灾难,严重的还会导致项目失败。《语义化版本》规范就是为了避免这些问题,但是很多小伙伴看着长长规范,进而产生了抵抗心理,这里整理了一个简......