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学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. UVA 12034 Race

    https://vjudge.net/problem/UVA-12034 题意:n个人比赛,有多少种可能的结果 假设i个人中,有j个人是第一名,方案数为C(i,j) 所以ans=Σ C(n,j)* f ...

  2. job源码分析

    /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agree ...

  3. sqlserver 个人整理

    1.创建临时表(临时表的生命周期是当前回话中) //创建临时表是使用#+表名 //判断临时表是否存在 if object_id('tempdb..#ttt1') is not null Begin d ...

  4. elasticsearch client

    你可以用client做很多事情: 在集群中执行index, get, delete, search,update 操作 在集群中执行administrative tasks 如果你想再程序中嵌入ela ...

  5. python学习笔记(五)数值类型和类型转换

    Python中的数值类型有: 整型,如2,520 浮点型,如3.14159,1.5e10 布尔类型 True和False e记法: e记法即对应数学中的科学记数法 >>> 1.5e1 ...

  6. 前端&后端程序员必备的Linux基础知识

    一 从认识操作系统开始 1.1 操作系统简介 我通过以下四点介绍什么操作系统: 操作系统(Operation System,简称OS)是管理计算机硬件与软件资源的程序,是计算机系统的内核与基石: 操作 ...

  7. Java面试通关要点汇总集(山东数漫江湖)

    这里,笔者结合自己过往的面试经验,整理了一些核心的知识清单,帮助读者更好地回顾与复习 Java 服务端核心技术.本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进行详细的剖析与解答.敬 ...

  8. HDU 1465 不容易系列之一 (错排公式+容斥)

    题目链接 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易,若想永远成功而总从不失败,那更是难上 ...

  9. python数据处理课程笔记(一)

    一.numpy 1.numpy中所有元素必须是相同的类型 a=[1,2,3,4,'t'] #列表中有str类型,转换为ndarray时所有元素都转换为str类型 arr1=np.array(a) pr ...

  10. bzoj 1296 DP

    对于每一行做DP预处理,w[i][j]代表这一行前i个刷j次的最大价值,那么w[i][j]=max(w[i][j],w[k][j-1]+sum[k+1][i]),sum[i][j]为i-j段刷一次最多 ...