最近公共祖先

对于有根树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. ZUFE OJ 2301 GW I (3)

    Description GW 是ZUFE的神犇,有一天他想到一种神奇的变换,并且将它命名为GW变换 对于一个数字n,该变换后的值GW(n)为,先令X=n 第一步,如果X为个位数,GW(n)=X,否则执 ...

  2. mysql中变量character_set_connection的具体作用

    如题.通常的使用中,character_set_client,character_set_connection这两个变量的值是一样的,也就是说查询不需要进行编码转换.这样看来变量character_s ...

  3. 基于Nginx的Rtmp流媒体服务器环境搭建

    一.编译安装 wget http://nginx.org/download/nginx-1.4.2.tar.gz wget https://github.com/arut/nginx-rtmp-mod ...

  4. javascript 回调, 单线程执行

    原文: http://www.cnblogs.com/aaronjs/p/3322466.html 这里的"回调"并不是"阻塞",而会空出执行线程,直至操作完成 ...

  5. EasyUi之datagird解读

    1.其json格式需要为:  JSON Code  1234567891011121314151617181920212223   {     ,     "rows": [    ...

  6. 17.4.3 使用MulticastSocket实现多点广播(2)

    // 让该类实现Runnable接口,该类的实例可作为线程的target public class MulticastSocketTest implements Runnable { // 使用常量作 ...

  7. SQL复习四(完整性约束)

    完整性约束是为了表的数据的正确性.主要有主键,外键的约束. 1 主键 当某一列添加了主键约束后,该列的数据就不能重复出现.这样每行记录中其主键列就能唯一的标识着以行.如学生可以用学号作为唯一的标识. ...

  8. memcache数据组织

    转自:原链接 使用命令 set(key, value) 向 memcached 插入一条数据, memcached 内部是如何组织数据呢 一 把数据组装成 item memcached 接受到客户端的 ...

  9. .NET反射

    反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息.使用反射可以看到一个程序集内部的接口.类.方法.字段.属性.特性等等信息.在System.Reflectio ...

  10. java线程 — 创建和启动线程

    创建和启动线程,传统有两种方式: 方式1:继承Thread类: 方式2:实现Runnable接口: 线程类(java.lang.Thread):Thread类和Thread的子类才能称之为线程类.阅读 ...