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 ...
随机推荐
- 【Foreign】咏叹 [模拟退火]
咏叹 Time Limit: 100 Sec Memory Limit: 256 MB Description 有n根木棍,第i根长度为ai.你要贴着墙围出一个矩形区域,木棍围成的矩形边缘必须平行或 ...
- bzoj 1878: [SDOI2009]HH的项链 ——树状数组+ 差分
Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得 ...
- quick-cocos2d-x数据存储 UserDefault GameState io
看了quick-cocos2d-x 的framework,发现里面有一个GameState,查了下,是数据存储的类,于是稍稍总结下我用到过的数据存储方式吧. 一共是三种方法: cc.UserDefau ...
- 重写strstr、strcpy、memcpy、memset、atof算法
#include<stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> ...
- hdu 1087 Super Jumping! Jumping! Jumping!(动态规划DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 Super Jumping! Jumping! Jumping! Time Limit: 200 ...
- CursorFileManager对cursor文件的读写
public class CursorFileManager implements CursorManager{public void write(String key, LongCursor cur ...
- 为什么IO多路复用需要采用非阻塞式IO
近段时间开始学习<Unix网络编程>,代码实现了一个简单的IO多路复用+阻塞式的服务端,在学习了非阻塞式IO后,有一个疑问,即: 假如调用了select,并且关注了几个描述字,当关注的描述 ...
- (二十)ubuntu的recovery mode解决用户一些实际问题
遇到的问题如下: 1.在当前用户下使用sudo来直接修改password等几个文件,一旦修改了passwd,用户名发生了变化,其他的用户组.密码等却没有对应的配置,就再进不了该用户了. 2.忘记用户密 ...
- jboss和tomcat有什么不同
2.tomcat 是 JSP/Servlet 容器jboss 是 JEE 容器,JEE 包括JSP/Servlet,JMS, EJB,JAX-WS,JAX-RS,CDI等等, tomcat是完全开源, ...
- kafka 设置消费者线程数
http://blog.csdn.net/derekjiang/article/details/9053863 分布式发布订阅消息系统 Kafka 架构设计 - 目前见到的最好的Kafka中文文章 M ...