最近公共祖先

对于有根树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. 关于有限状态机FSM同步复位的问题

    FSM通常情况下使用异步信号进行复位,如FSM1中的rst_n信号.当rst_n信号为低时,FSM进入空闲状态IDLE. 在某些特殊情况下有可能需要跟随某个外部信号强制切换到空闲状态,也即同步复位.下 ...

  2. js timer

    <html><head lang="en"> <meta charset="UTF-8"> <title>< ...

  3. arrayList LinkedList HashMap HashTable的区别

    ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦 LinkedList 采用的将对象存放在独立的空间中,而且在每个空间中还保存下一 ...

  4. CodeForces 617A Elephant

    C语言语法入门题 #include<cstdio> #include<cstring> #include<vector> #include<cmath> ...

  5. 如何获取app的素材,做出一个高仿的app

    第一步:在iTunes中搜索你想要的app,然后点击下载: 下载完成之后右键点击:在Finder中显示 在finder中右键用"归档工具打开" 会显示如下内容: "显示包 ...

  6. bzoj1562【Noi2009】变换序列

    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 给一个序列Di表示min(|i-Ti|,n-|i-Ti|),求一个字典序最小的序列Ti ...

  7. <Natural Language Processing with Python>学习笔记二

    用Enthought Canopy作图果然方便.昨天频频出现无法识别pylab模块的异常,今天终于搞好了.以下是今天出来的图:

  8. Powerbuilder编程技巧 如何获取网页的HTML源码

    直接使用的三种方式 1.  PB内部对象 Inet object 2.  API 函数 3.  Ole中的Microsfot Web 游览器对象 一.Inet object: 1.Inet objec ...

  9. ios 字体设计

    ref: http://ju.outofmemory.cn/entry/217705 ref:http://gold.xitu.io/entry/57958a41128fe10056be13b1 下面 ...

  10. PHP的高并发和大数据处理

    收集前人的经验.加速学习,解决工作中的难题. 一.代码优化(包括sql语句的优化), 合理的使用索引,避免整表查询.二.日常海量数据处理我用文件缓存,文件缓存分两种,第一种是最常见的生成html静太文 ...