最近公共祖先

对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n,q;
int cnt,head[],r[],deep[],p[][];
struct node{
int v;
int next;
}s[]; void add(int u,int v){
s[++cnt].v=v;
s[cnt].next=head[u];
head[u]=cnt;
} void DFS(int x){//预处理深度
for(int i=head[x];i;i=s[i].next){
int V=s[i].v;
if(!deep[V]){
deep[V]=deep[x]+;
p[V][]=x;
DFS(V);
}
}
} void init(){//p[i][j]表示i的第2^j的祖先
for(int j=;(<<j)<=n;++j)
for(int i=;i<=n;++i)
if(p[i][j-]!=-)
p[i][j]=p[p[i][j-]][j-];//i的2^j的祖先-->i的2^(j-1)的祖先的2^(j-1)的祖先
} int LCA(int a,int b){
if(deep[a]<deep[b])swap(a,b);
int i;
for(i=;(<<i)<=deep[a];++i);
--i;
for(int j=i;j>=;--j)//使a,b在相同深度
if(deep[a]-(<<j)>=deep[b])a=p[a][j];
if(a==b)return a;
for(int j=i;j>=;--j)//LCA
if(p[a][j]!=-&&p[a][j]!=p[b][j]){
a=p[a][j];
b=p[b][j];
}
return p[a][];
} int main(){
scanf("%d",&n);
for(int i=;i<n;++i){
int x,y;
scanf("%d%d",&x,&y);
++r[y];
add(x,y);
}
int rt;
for(int i=;i<=n;++i)if(r[i]==){rt=i;break;}
memset(p,-,sizeof(p));
p[rt][]=rt;
DFS(rt);
init(); scanf("%d",&q);
for(int i=;i<=q;++i){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}

LCA 倍增的更多相关文章

  1. 【codevs2370】小机房的树 LCA 倍增

    2370 小机房的树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...

  2. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

  3. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

  4. CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)

    CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...

  5. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  6. POJ.1330 Nearest Common Ancestors (LCA 倍增)

    POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...

  7. LCA(倍增在线算法) codevs 2370 小机房的树

    codevs 2370 小机房的树 时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...

  8. LCA(最近公共祖先)——LCA倍增法

    一.前人种树 博客:最近公共祖先 LCA 倍增法 博客:浅谈倍增法求LCA 二.沙场练兵 题目:POJ 1330 Nearest Common Ancestors 代码: const int MAXN ...

  9. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

  10. 次小生成树(LCA倍增)

    算法: 求出MST之后枚举每条在MST之外的边 连上之后会出现环 找到环中除加上的边之外权值最大的边 删除该边之后得到一颗新树 做法: 利用LCA倍增地维护最小生成树上两点之间的最大边权 每次枚举在M ...

随机推荐

  1. python之路: 线程、进程和协程

    进程和线程 既然看到这一章,那么你肯定知道现在的系统都是支持“多任务”的操作,比如: Mac OS X,UNIX,Linux,Windows等. 多任务:简单地说就是同时运行多个任务.譬如:你可以一边 ...

  2. IWorkSpace接口介绍 1.打开各种数据库

    IWorkspace接口提供访问工作空间的通用属性和方法,如它的连接属性,以及包含的数据集的方法. IWorkspace的成员字段: Members   Description ConnectionP ...

  3. CodeForces 609D Gadgets for dollars and pounds

    二分天数+验证 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm&g ...

  4. CSS——宽高问题大汇总

    1.宽高继承 他们是要属性的,并不是直接就能继承,inherit. 2.浮动的盒子不要给宽,宽度由内容来决定

  5. iReport使用教程

    http://www.blogjava.net/keweibo/articles/239492.html 原创出处 http://blog.163.com/liushuo216@126/blog/st ...

  6. TweenLite JS版

    今早逛网站看到下面这个帖子: 译~GreenSock动画平台(GSAP)的JavaScript版本入门 这个就是做ActionScript 的时候用得最多的第三方缓动包TweenLite了, 就此标记 ...

  7. HDU 2412 Party at Hali-Bula

    树形DP水题.判断取法是否唯一,dp的时候记录一下每个状态从下面的子节点推导过来的时候是否唯一即可. #include<cstdio> #include<cstring> #i ...

  8. WPF教程:附加属性

    一.附加属性的特点1.特殊的依赖属性2.用于非定义该属性的类 例如Grid面板的RowDefinition.ColumnDefinition.Canvas面板的Left.RightDockPanel面 ...

  9. 不小心删掉root目录......

    1.先保存还剩下的的东西,比如说桌面的文件,保存在/下面其他目录 2.执行命令 cp -R /etc/skel/.[!.]* ./ 3.reboot

  10. objective-c之各种数值

    各种数值 NSArray和NSDictionary都只能存储对象,不能存储任何基本类型的数据,如int,float,struct.因此我们可以用对象来封装基本的数值. NSNumber Cocoa提供 ...