第一种是离线的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. java生成简单验证码图片

    概要 最近项目需要用java实现输出随机验证码图片到前台,正好有机会接触下java的绘图类,完成需求后也有时间做个总结,写篇随笔记录下也希望能帮助到有同样需求的人! 需求流程图 1.生成随机数 在ja ...

  2. vue.js 自定义事件

    <div id="app"> <h2>{{num}}</h2> <h1>全局组件</h1> <my-compone ...

  3. (Python基础)字符编码与转码

    ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧 ...

  4. 基于KMP算法的字符串模式匹配问题

    基于KMP算法的字符匹配问题 反正整个清明都在纠结这玩意...差点我以为下个清明要给自己过了. 至于大体的理解,我就不再多说了(还要画图多麻烦鸭),我参考了以下两个博客,写的真的不错,我放了超链接,点 ...

  5. QTP测试.NET程序的时候,ComboBox下拉框控件选择后,运行时对象不可见解决方案

    解决方法: 录制时,选择下拉框数据的时候,不要鼠标单击选择,而是要用ENTER(回车键)来选择,才能完成选择,这样录制就OK了.

  6. PHP截取特定字符串前后

    $email   =  '13366540193@163.com' ;$domain  =  strstr ( $email ,  '@' );echo  $domain ;  // 打印 @163. ...

  7. urllib、urllib2、urllib3区别和使用

    python3中把urllib和urllib合并为一个库了,urllib对应urllib.request 1.) python 中最早内置拥有的网络请求模块就是 urllib,我们可以看一下 urll ...

  8. 百度地图点聚合MarkerClusterer性能优化

    公司要求做个百度地图点聚合的性能优化,需一次性加载9万条数据. 记录下自己的优化过程.(只想看优化代码的可直接移步:步骤三) 一.引入百度地图 vue项目中,在index.html文件中用script ...

  9. Android转换集合数据(ArrayList)为Json格式并上传服务器

    使用Gson上传集合数据到服务器,1.最外层用 ArrayMap<String, Object> 封装:2.通过  mRequestParam.put("cmdLineIds&q ...

  10. MVC ScriptBundle自定义排序。

    今天发现MVC的ScriptBundle @Scripts.Render()后是按照我也不知道顺序显示在页面上的,后果就是jquery.min.js被排在了后面(反正我下面那堆默认jquery.min ...