TarjanLCA学习笔记
1.前言
首先我们介绍的算法是LCA问题中的离线算法-Tarjan算法,该算法采用DFS+并查集,再看此算法之前首先你得知道并查集(尽管我相信你如果知道这个的话肯定是知道并查集的),Tarjan算法的优点在于相对稳定,时间复杂度也比较居中,也很容易理解(个人认为)。
2.思想
下面详细介绍一下Tarjan算法的思想:
1.任选一个点为根节点,从根节点开始。
2.遍历该点u所有子节点v,并标记这些子节点v已被访问过。
3.若是v还有子节点,返回2,否则下一步。
4.合并v到u上。
5.寻找与当前点u有询问关系的点v。
6.若是v已经被访问过了,则可以确认u和v的最近公共祖先为v被合并到的父亲节点a。
从上面步骤可以看出,Tarjan算法要用到并查集。这里,我们使用链式前向星来存储边和询问情况。
3.算法实现
不妨以洛谷P3379:LCA模板题为例题
#include<cstdio>
#include<cstring> const int maxn = 5e5 + ,maxm = 5e5 + ;
int fa[maxn],fir[maxn],frt[maxn],ans[maxm],n,m,s,tot,id;
bool flag[maxn];
//存边
struct Edge{
int v,next;
}e[maxn << ];
//存询问
struct Ques{
int v,next,qid;
}q[maxm << ];
//加边
void addEdge(int u,int v){
e[tot] = (Edge){v,fir[u]};
fir[u] = tot++;
e[tot] = (Edge){u,fir[v]};
fir[v] = tot++;
}
//加询问
void addQues(int u,int v,int qid){
q[id] = (Ques){v,frt[u],qid};
frt[u] = id++;
q[id] = (Ques){u,frt[v],qid};
frt[v] = id++;
}
//读入优化
inline int read(){
int sum = ;
char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){sum = sum * + ch - ''; ch = getchar();}
return sum;
}
//输出优化
void write(int x){
if(x / ) write(x / );
putchar(x % + '');
}
//寻找父亲
int find(int x){
if(fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
//合并
void unionn(int x,int y){
int fx = find(x),fy = find(y);
fa[fx] = fy;
}
//离线操作(u表示当前点,fa表示该点的前驱点)
void dfs(int u,int fa){
flag[u] = true;//标记已访问
//遍历所有与u相连的点
for(int i = fir[u];i != -;i = e[i].next){
int v = e[i].v;
//如果v不是u的前驱
if(v != fa){
dfs(v,u);//遍历下一层
//寻找是否有询问关系
for(int j = frt[v];j != -;j = q[j].next){
int k = q[j].v;
if(flag[k])
ans[q[j].qid] = find(k);
}
unionn(v,u);//连接
}
}
}
//主函数
int main(){
n = read(),m = read(),s = read();
memset(fir,-,sizeof(fir));
memset(frt,-,sizeof(frt));
for(int i = ;i < n;i++){
fa[i] = i;
int x = read(),y = read();
addEdge(x,y);
}
fa[n] = n;
for(int i = ;i <= m;i++){
int x = read(),y = read();
addQues(x,y,i);
}
dfs(s,-);
//因为这里已经给出根了,直接从根开始
for(int i = ;i <= m;i++,putchar('\n')) write(ans[i]);
return ;
}
TarjanLCA学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
随机推荐
- BZOJ2733:使用并查集维护连通性之后用线段树维护+线段树合并(动态开点)
可以说是线段树合并的裸题吧 题意就是给你两个操作 一个操作是合并两个集合,这两个集合都是用权值线段树维护的,便于查询第k小元素 另一个操作就是查询区间极值了 #include<cstdio> ...
- Linux系统关闭防火墙端口
1. 打开防火墙端口 # iptables -I INPUT -p tcp --dport -j ACCEPT # iptables -I INPUT -p tcp --dport -j ACCEPT ...
- SpringBoot 在CentOS7部署,注册为服务,开机启动
1.首先在maven工程的pom文件中引入以下标签并保存 <build> <plugins> <plugin> <groupId>org.springf ...
- Linux SSH 无密码登录
1. ssh-keygen -t rsa 2. scp root@ip:/root/.ssh/id_rsa.pub ./id2 3. cat id2 >> authtorized_keys ...
- bzoj 2957: 楼房重建 ——线段树
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
- PKUWC 2019 自闭记
PKUWC 2019 自闭记 Day -1 考前天天在隔壁的物竞教室划水(雀魂,能和吉老师一起玩的游戏都是好游戏),没有做题. Day 0 早上8:16的高铁,到广州南居然要6个小时...不知道福州和 ...
- Python标准库笔记(2) — re模块
re模块提供了一系列功能强大的正则表达式(regular expression)工具,它们允许你快速检查给定字符串是否与给定的模式匹配(match函数), 或者包含这个模式(search函数).正则表 ...
- Vuex 基本概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 每一个 Vuex 应用的核心就是 stor ...
- GCC在C语言中内嵌汇编 asm __volatile__ 【转】
转自:http://blog.csdn.net/pbymw8iwm/article/details/8227839 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达 ...
- 转载: GIt远程操作详解
Git远程操作详解 作者: 阮一峰 日期: 2014年6月12日 Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能. Git有很多优势,其中之一就是远程操作非常简便.本文详细介 ...