第一种是离线的Tarjan算法

#include<cstdio>
using namespace std;
int rd(){
int x=,fl=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-'){fl=-;}ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ch^);ch=getchar();}
return fl*x;
}
int n,m,s,x,y,num1,num2;
int f[],dis[],a[][],hd1[],hd2[];
bool vis[];
struct star{int nt,to,ds;}e[],e2[];
void add1(int from,int to){
e[++num1].nt=hd1[from];
e[num1].to=to;
hd1[from]=num1;
}
void add2(int from,int to,int ds){
e2[++num2].nt=hd2[from];
e2[num2].to=to;
e2[num2].ds=ds;
hd2[from]=num2;
}
int find(int x){
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
void un(int x,int y){
int ra=find(x),rb=find(y);
f[ra]=rb;
}
void tarjan(int x){
vis[x]=;
for(int i=hd2[x];i;i=e2[i].nt){
int to=e2[i].to,dis=e2[i].ds;
if(vis[to])
a[dis][]=find(to);
}
for(int i=hd1[x];i;i=e[i].nt){
int to=e[i].to;
if(!vis[to]){
tarjan(to);
un(to,x);
}
}
}
int main(){
n=rd();m=rd();s=rd();
for(int i=;i<n;i++){
x=rd();y=rd();
add1(x,y);add1(y,x);
}
for(int i=;i<=m;i++){
x=rd();y=rd();
a[i][]=x;a[i][]=y;
add2(x,y,i);add2(y,x,i);
}
for(int i=;i<=n;i++)f[i]=i;
tarjan(s);
for(int i=;i<=m;i++)
printf("%d\n",a[i][]);
return ;
}

这个代码跑的飞快但是不太好理解。。

还有一种用倍增的思想

#include<iostream>
#include<cstdio>
using namespace std;
int rd(){
int x=,fl=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-'){fl=-;}ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ch^);ch=getchar();}
return fl*x;
}
int n,m,x,y,s,num=,hd[],dep[],f[][];
struct star{int nt,to;}e[];
void add(int fm,int to){e[++num].to=to;e[num].nt=hd[fm];hd[fm]=num;}
void dfs(int x,int fa){
dep[x]=dep[fa]+;
for(int i=;i<=;i++)
f[x][i]=f[f[x][i-]][i-];
for(int i=hd[x];i;i=e[i].nt)
{
int to=e[i].to;
if(to==fa)continue;
f[to][]=x;
dfs(to,x);
}
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[f[u][i]]>=dep[v])
u=f[u][i];
if(u==v)return u;
}
for(int i=;i>=;i--)
if(f[u][i]!=f[v][i]){
u=f[u][i];v=f[v][i];
}
return f[u][];
}
void print(int x){
if(x<){putchar('-');x=-x;}
if(x>)print(x/);
putchar(x%+'');
}
int main(){
n=rd();m=rd();s=rd();
for(int i=;i<n;i++){
x=rd();y=rd();
add(x,y);add(y,x);
}
dfs(s,);
for(int i=;i<=m;i++){
x=rd();y=rd();
print(lca(x,y));
putchar('\n');
}
return ;
}

emmm....这种比较好理解但是跑的有点慢...

如果不太懂...可以看这个/**/

其实还有一种bfs版的玄学算法也安利一下

/* */

LCA的两种写法的更多相关文章

  1. ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法

    ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块  --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...

  2. EF架构~linq模拟left join的两种写法,性能差之千里!

    回到目录 对于SQL左外连接我想没什么可说的,left join将左表数据都获出来,右表数据如果在左表中不存在,结果为NULL,而对于LINQ来说,要实现left join的效果,也是可以的,在进行j ...

  3. 运算符关键字。数据区别大小写。日期范围。判空的两种写法。NOT IN的两种写法。IN范围可含NULL,但NOT IN值范围不能含NULL。

    比较:>,<,=,>=,<=,<>(!=) 逻辑:AND,OR,NOT 范围:BETWEEN...AND... 范围:IN,NOT IN 判空:IS NULL, I ...

  4. 快速排序partition过程常见的两种写法+快速排序非递归实现

    这里不详细说明快速排序的原理,具体可参考here 快速排序主要是partition的过程,partition最常用有以下两种写法 第一种: int mypartition(vector<int& ...

  5. java 路径分隔符File.separator 以及 路径两种写法"/"和"\\"

    一.File.separator File file=new File(); 这句是新建一个文件.file.separator这个代表系统目录中的间隔符,说白了就是斜线,不过有时候需要双线,有时候是单 ...

  6. iOS中表视图单元格事件用nib和storyboard的两种写法总结

    从ios6开始,苹果公司推出了storyborad技术取代了nib的写法,这样代码量确实少写了很多,也比较简洁.但是,从学习的角度来说,阿堂认为 用nib的写法,虽然多了些代码,但是对于掌握知识和原理 ...

  7. linq和ef关于group by取最大值的两种写法

    LINQ: var temp = from p in db.jj_Credentials group p by p.ProfessionID into g select new { g.Key, Ma ...

  8. ThinkPHP中Widget的两种写法及调用

    Widget扩展一般用于页面组件的扩展,在页面根据需要输出不同的内容,下面介绍一下ThinkPHP中Widget的两种写法及调用 写法一: ArticlWidget.class.php文件: clas ...

  9. es6对象内函数的两种写法

    es6对象内函数一般有两种写法: var person1 = { name: "p1", sayThis() { console.log(this); } }; var perso ...

随机推荐

  1. C#压缩文件,C#压缩文件夹,C#获取文件

    using System; using System.Data; using System.Configuration; using System.Collections.Generic; using ...

  2. MPI 集合通信函数 MPI_Reduce(),MPI_Allreduce(),MPI_Bcast(),MPI_Scatter(),MPI_Gather(),MPI_Allgather(),MPI_Scan(),MPI_Reduce_Scatter()

    ▶ 八个常用的集合通信函数 ▶ 规约函数 MPI_Reduce(),将通信子内各进程的同一个变量参与规约计算,并向指定的进程输出计算结果 ● 函数原型 MPI_METHOD MPI_Reduce( _ ...

  3. PG数据库基本命令——查询(笔记)

    1.插入数据(insert 语句) 语法: INSERT INTO TABLE_NAME (column1, column2, column3,...columnN) VALUES (value1, ...

  4. python实现将android手机通讯录vcf文件转化为csv

    经常会遇到将手机通讯录导出到电脑并转化为在电脑中可编辑的情况,在网上搜索了很久当前不外乎两种处理方式.1.使用电脑的outlook的通讯簿功能,将手机导出的vcf文件导入到outlook的通讯录中,然 ...

  5. POIUtils 导出 poi Test 100w 600w 条数据

    依赖: <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-l ...

  6. XML文档的生成和解析操作方法

    XML文档和JSon文档同为网络传输中的数据格式,JSon的解析和创建已经在新浪微博的使用中相当熟悉,故仅仅记载XML文档的相关方法. 关于XML文档: 1.一种便于编辑和传输的数据文件格式 2.xm ...

  7. 【399】jupyter 修改主题

    参考:Jupyter 主题更换 参考:Restoring default theme #86 修改主题的方法: 首先在 cmd 上输入 jt -l 选择自己需要的主题,如 jt -t monokai ...

  8. 导入大数据量sql时候超时的问题

    D:\Visual-NMP-x64\Bin\MySQL\bin这个是你mysql的路径 mysqldump.exe -h服务器信息 -umysql的用户名 -pmysql的密码 数据库名 > 要 ...

  9. cookies,sessionstorage,localstorage的区别?

    请描述一下 cookies,sessionStorage 和 localStorage 的区别? sessionStorage 和 localStorage 是HTML5 Web Storage AP ...

  10. kettle使用笔记1--基本安装和使用

    参考来源 https://blog.csdn.net/qq_36698956/article/details/80751655,在这个文章基础上实际使用增加的. 一,安装,采用的是下载官方网站的win ...