第一种是离线的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. 使用NPM安装Vue项目

    使用NPM安装Vue项目步骤如下: 一.先安装node.js,下载node.js安装包,node.js安装成功之后,左击电脑左下角>运行>输入cmd,如下图所示: 二.点击确定进入,分别在 ...

  2. Windows下安装MySQL5.7.18的方法

    准备: 操作系统:win7 下64位的zip版本的MySQL,路径:http://dev.mysql.com/downloads/mysql/ 我下的是最新版的MySQL,解压后,目录如下: 可以看到 ...

  3. 13. nginx,lvs之一

    摘要: 1.详细描述常见nginx常用模块和模块的使用示例 2.简述Linux集群类型.系统扩展方式及调度方法 3.简述lvs四种集群有点及使用场景 4.描述LVS-NAT.LVS-DR的工作原理并实 ...

  4. Echarts修改提示框及自定义提示框内容

    1:首先先定义自定义的json数据 var msg = [{ 'tell':'110', 'ContentMessage':"我今天去吃大餐" },{ 'tell':'111', ...

  5. js自执行事件

    let a = document.createElement("a");let event = new MouseEvent("click");a.downlo ...

  6. python_11 装饰器,闭包

    装饰器:本质就是函数,功能是为其他函数添加附加功能 原则: 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 装饰器的知识储备 装饰器=高阶函数+函数嵌套+闭包 #装饰器: def tim ...

  7. Spark-shell错误:Missing Python executable 'python', defaulting to ...

    最近博主因为学习<云计算导论>一课,需要在Windows上搭建Saprk,故在网上找了相关教程搭建,步骤如下: 1. Scala 2.Spark 3.Handoop 但是不管博主怎么修正, ...

  8. Windows 7升级1月更新汇总后导致SMBv2网络无法正常工作

    在本月的补丁星期二活动日中,微软面向Windows 7.Windows 2008 R2服务器系统推出了KB4480970的月度更新汇总.然而根据部分用户反馈,在安装该更新之后导致系统的网络设置无法正常 ...

  9. [原创] debian 9.3 搭建seafile企业私有网盘

    [原创] debian 9.3 搭建seafile企业私有网盘 需求是这样的, 个人疲惫于 "成为大伙的文件中转站" ,公司不管大大小小的文件,都要打电话过来“转个xx文件”.“帮 ...

  10. std::condition_variable::wait_until segment

    原因是使用了 -static 改为 -static-libstdc++ -static-libgcc