LCA的两种写法
第一种是离线的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的两种写法的更多相关文章
- ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法
ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块 --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...
- EF架构~linq模拟left join的两种写法,性能差之千里!
回到目录 对于SQL左外连接我想没什么可说的,left join将左表数据都获出来,右表数据如果在左表中不存在,结果为NULL,而对于LINQ来说,要实现left join的效果,也是可以的,在进行j ...
- 运算符关键字。数据区别大小写。日期范围。判空的两种写法。NOT IN的两种写法。IN范围可含NULL,但NOT IN值范围不能含NULL。
比较:>,<,=,>=,<=,<>(!=) 逻辑:AND,OR,NOT 范围:BETWEEN...AND... 范围:IN,NOT IN 判空:IS NULL, I ...
- 快速排序partition过程常见的两种写法+快速排序非递归实现
这里不详细说明快速排序的原理,具体可参考here 快速排序主要是partition的过程,partition最常用有以下两种写法 第一种: int mypartition(vector<int& ...
- java 路径分隔符File.separator 以及 路径两种写法"/"和"\\"
一.File.separator File file=new File(); 这句是新建一个文件.file.separator这个代表系统目录中的间隔符,说白了就是斜线,不过有时候需要双线,有时候是单 ...
- iOS中表视图单元格事件用nib和storyboard的两种写法总结
从ios6开始,苹果公司推出了storyborad技术取代了nib的写法,这样代码量确实少写了很多,也比较简洁.但是,从学习的角度来说,阿堂认为 用nib的写法,虽然多了些代码,但是对于掌握知识和原理 ...
- 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 ...
- ThinkPHP中Widget的两种写法及调用
Widget扩展一般用于页面组件的扩展,在页面根据需要输出不同的内容,下面介绍一下ThinkPHP中Widget的两种写法及调用 写法一: ArticlWidget.class.php文件: clas ...
- es6对象内函数的两种写法
es6对象内函数一般有两种写法: var person1 = { name: "p1", sayThis() { console.log(this); } }; var perso ...
随机推荐
- Openstack EOL 版本离线安装源
当Openstack EOL,网上的yum源无法安装openstack版本和rdo ,则无法正常通过yum源直接安装openstack和rdo ,只是直接安装openstack后,也无法通过yum源 ...
- Mac端StartUML的安装和破解
**本人安装的是StarUML-3.0.1版本** 一.下载与安装 1. 从官方网站下载,网址:http://staruml.io/ 2. dmg文件下载完成后,双击安装. 二.破解 1. 安装npm ...
- boost的named_mutex的一些坑
最近遇到一个问题,程序在a用户下运行后,然后注销windows,登陆b用户,发现程序奔溃,抓了下堆栈,发现了boost的named_mutex一些细节,记录下 #include <boost/i ...
- 记录一次JQuery 动态参数使用
之前动态id 使用时时候一直是复制黏贴的,到自己实际使用的时候却毫无印象,这样不可取呀 $('#id') 取的是 id=‘id’ 的元素 $('#'+id) 才是取id为动态值的时候正确写法 记录 ...
- 3.Telnet探测端口后怎么退出
使用 'Ctrl' + ' ] ' 一起按退出
- java学习-- String
String 类的实例是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了 String 类是不可改变的解析,例如: String s = "Google"; ...
- Interlij idea
https://blog.csdn.net/qq_30180559/article/details/79146795 http://baijiahao.baidu.com/s?id=157736618 ...
- 面试必备:ArrayList源码解析(JDK8)
面试必备:ArrayList源码解析(JDK8) https://blog.csdn.net/zxt0601/article/details/77281231 概述很久没有写博客了,准确的说17年以来 ...
- Version Control/Git,SVN
一.Version Control 1.什么是Version Control 版本控制(Version Control)是指对软件开发过程中各种程序代码.配置文件及说明文档等文件变更的管理,是软件配置 ...
- 小乌龟 coding 克隆、提交一直提示无权限
因为之前设置过账号,但是网上各种命令行清除都没有用,进入小乌龟设置删除全局配置,系统配置,保存就可以克隆等操作了