我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况:

1.两结点的深度相同.

2.两结点深度不同.

第一步都要转化为情况1,这种可处理的情况。

先不考虑其他, 我们思考这么一个问题: 对于两个深度不同的结点, 把深度更深的那个向其父节点迭代, 直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA。求LCA使用倍增法,倍增的条件是找到相同的祖先,减小步距。

/*
* LCA在线算法(倍增法)
*/
const int MAXN = 10010;
const int DEG = 20; struct Edge
{
int to, next;
} edge[MAXN * 2]; int head[MAXN], tot;
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} void init()
{
tot = 0;
memset(head, -1, sizeof(head));
} int fa[MAXN][DEG]; // fa[i][j]表示结点i的第2^j个祖先
int deg[MAXN]; // 深度数组 void BFS(int root)
{
queue<int>que;
deg[root] = 0;
fa[root][0] = root;
que.push(root);
while (!que.empty())
{
int tmp = que.front();
que.pop();
for (int i = 1; i < DEG; i++)
{
fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
}
for (int i = head[tmp]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa[tmp][0])
{
continue;
}
deg[v] = deg[tmp] + 1;
fa[v][0] = tmp;
que.push(v);
}
}
} int LCA(int u, int v)
{
if (deg[u] > deg[v])
{
swap(u, v);
}
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for (int det = hv-hu, i = 0; det ; det >>= 1, i++)
{
if (det & 1)
{
tv = fa[tv][i];
}
}
if (tu == tv)
{
return tu;
}
for (int i = DEG - 1; i >= 0; i--)
{
if (fa[tu][i] == fa[tv][i])
{
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][0];
} bool flag[MAXN]; int main()
{
int T;
int n;
int u, v;
scanf("%d", &T); while(T--)
{
scanf("%d", &n);
init();
memset(flag, false, sizeof(flag));
for (int i = 1; i < n; i++)
{
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
flag[v] = true;
}
int root;
for (int i = 1; i <= n; i++)
{
if (!flag[i])
{
root = i;
break;
}
}
BFS(root);
scanf("%d%d", &u, &v);
printf("%d\n", LCA(u, v));
}
return 0;
}

树上倍增法求LCA的更多相关文章

  1. 倍增法求lca(最近公共祖先)

    倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...

  2. HDU 2586 倍增法求lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. 倍增法求LCA

    倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...

  4. 在线倍增法求LCA专题

    1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自 ...

  5. 倍增法求LCA(最近公共最先)

    对于有根树T的两个结点u.v,最近公共祖先x=LCA(u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,根据定义可以看出14和15的最近公共祖先是10,   15和16的最近公共 ...

  6. 倍增法求lca:暗的连锁

    https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...

  7. 倍增法求LCA代码加详细注释

    #include <iostream> #include <vector> #include <algorithm> #define MAXN 100 //2^MA ...

  8. 最近公共祖先算法LCA笔记(树上倍增法)

    Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了 ...

  9. 倍增 Tarjan 求LCA

                                                                                                         ...

随机推荐

  1. 计算机网络协议,IPV4数据报分析

    一.IP数据报结构分析 1.整体结构 一个IP数据报由首部和数据两部分组成. 首部的前一部分固定长20字节,这是所有IP数据报必须具有的:在首部的固定部分后面是一些可选字段,其长度是可变的. IP数据 ...

  2. postman 工具接口测试

    一.get:请求多个参数时,需要用&连接 eg:http://api.***.cn/api/user/stu_info?stu_name=小黑&set=女   eg:接口请求参数放在b ...

  3. 20 java 基础回顾--中阶引入

    一.数据类型 基本数据类型(共:四类八种) 整数 byte short int long 浮点 float double 字符 char 布尔 boolean 引用数据类型(new的数据) Stude ...

  4. AJ学IOS(27)UI之iOSUIKit字符属性NSAttributedString概述

    AJ分享,必须精品 UIKit字符属性NSAttributedString概述 字符属性 字符属性可以应用于 attributed string 的文本中. NSString *const NSFon ...

  5. OSI 七层模型以及TCP/IP模型

    OSI 七层模型 定义 OSI(Open System Interconnection)即开放式系统互联通信参考模型.该模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一 ...

  6. stand up meeting 11/18/2015

    今日工作总结: 冯晓云:完成C#版本API的class library编译,尝试与主程序进行通信:昨天临时通知让用C++封装,不解!!![后续:我用C#做了一个查词的APP,调用的就是这个API的DL ...

  7. vue的组件通讯

    Vue的组件通讯又称组件传值 一.父子组件传值: 父组件: <子组件名   :动态变量名 (随便起)='你想要传递的数据' ></子组件名> 子组件: 利用 prop去接收父组 ...

  8. T - Nash Matrix CodeForces - 1316D

    题意: 输入n行数,没行由2*n个数,表示一个坐标(x,y). 如果x和y==-1表示从该点(i,j)出发,按照构造的前移动不会停下. 否则就要到点(x,y)处停下. 题解: 首先处理-1  枚举每个 ...

  9. 微信小程序 —搜索框

    wxSearch优雅的微信小程序搜索框 一.功能 支持自定义热门key 支持搜索历史 支持搜索建议 支持搜索历史(记录)缓存 二.使用 1.将wxSearch文件夹整个拷贝到根目录下 2.引入 // ...

  10. 下载mp4文件

    实现mp4文件的下载,而不是在线播放 <!DOCTYPE html> <html lang="en"> <head> <meta char ...