A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:

 
In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node y if node x is in the path between the root and node y. For example, node 4 is an ancestor of node 16. Node 10 is also an ancestor of node 16. As a matter of fact, nodes 8, 4, 10, and 16 are the ancestors of node 16. Remember that a node is an ancestor of itself. Nodes 8, 4, 6, and 7 are the ancestors of node 7. A node x is called a common ancestor of two different nodes y and z if node x is an ancestor of node y and an ancestor of node z. Thus, nodes 8 and 4 are the common ancestors of nodes 16 and 7. A node x is called the nearest common ancestor of nodes y and z if x is a common ancestor of y and z and nearest to y and z among their common ancestors. Hence, the nearest common ancestor of nodes 16 and 7 is node 4. Node 4 is nearer to nodes 16 and 7 than node 8 is.

For other examples, the nearest common ancestor of nodes 2 and 3 is node 10, the nearest common ancestor of nodes 6 and 13 is node 8, and the nearest common ancestor of nodes 4 and 12 is node 4. In the last example, if y is an ancestor of z, then the nearest common ancestor of y and z is y.

Write a program that finds the nearest common ancestor of two distinct nodes in a tree.

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case starts with a line containing an integer N , the number of nodes in a tree, 2<=N<=10,000. The nodes are labeled with integers 1, 2,..., N. Each of the next N -1 lines contains a pair of integers that represent an edge --the first integer is the parent node of the second integer. Note that a tree with N nodes has exactly N - 1 edges. The last line of each test case contains two distinct integers whose nearest common ancestor is to be computed.

Output

Print exactly one line for each test case. The line should contain the integer that is the nearest common ancestor.

Sample Input

2
16
1 14
8 5
10 16
5 9
4 6
8 4
4 10
1 13
6 15
10 11
6 7
10 2
16 3
8 1
16 12
16 7
5
2 3
3 4
3 1
1 5
3 5

Sample Output

4
3
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N=1E4+;
bool pre[N];
vector<int >ve[N];
typedef long long ll;
ll bits[];
int depth[N],fa[N][];
void inint(){
bits[]=;
for(int i=;i<=;i++) bits[i]=bits[i-]<<;
}
void dfs(int x,int y){
depth[x]=depth[y]+;
fa[x][]=y;
for(int i=;i<=;i++){
fa[x][i]=fa[fa[x][i-]][i-];
}
for(int i=;i<ve[x].size();i++){
int x1=ve[x][i];
if(x1!=y){
dfs(x1,x);
}
}
}
int lca(int x,int y){
if(depth[x]<depth[y]) swap(x,y);
int dif=depth[x]-depth[y];
for(int i=;i>=;i--){
if(dif>=bits[i]){
x=fa[x][i];
dif-=bits[i];
}
}
if(x==y) return x;
for(int i=;i>=;i--){
if(depth[x]>=bits[i]&&fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][];
} int main(){
int t;
inint();
scanf("%d",&t);
while(t--){
memset(pre,,sizeof(pre));
memset(fa,,sizeof(fa));
memset(depth,,sizeof(depth));
int n;
scanf("%d",&n);
int x,y;
for(int i=;i<=n-;i++){
scanf("%d%d",&x,&y);
ve[x].push_back(y);
ve[y].push_back(x);
pre[y]=;
}
int ancestor; for(int i=;i<=n;i++){
if(pre[i]==){
ancestor=i;
break;
}
}
dfs(ancestor,);
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y)); for(int i=;i<=n;i++){
ve[i].clear();
}
}
return ;
}

还可以用 暴力 朴素算法来算

#include<stdio.h>///LCA最近公共祖先查询,朴素算法
#include<string.h>
int fa[]; int deep(int x)///计算x节点深度
{
int cnt=;
while(x)
{
cnt++;
x=fa[x];
}
return cnt;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
memset(fa,,sizeof(fa));///该数组记录每个节点的父亲,根节点父亲为0
int s,f;
scanf("%d",&n);
for(int i=;i<n-;i++){
scanf("%d%d",&f,&s);
fa[s]=f;
} int a,b;
scanf("%d%d",&a,&b);
int x1=deep(a),y1=deep(b);
//只是用深度做了一个判断 取了一个差。
if(x1<y1)///查询的深度若两个节点深度不同,将较深的节点先上移
{
int tt=y1-x1;
while(tt--)
b=fa[b];
}
else if(x1>y1){
int tt=x1-y1;
while(tt--)
a=fa[a];
} while(a!=b)///两个节点深度相同时同时向上寻找父亲,直到父亲相同
a=fa[a],b=fa[b];
printf("%d\n",a);
}
}

LCA Nearest Common Ancestors (很典型的例题)的更多相关文章

  1. 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18136   Accept ...

  2. POJ 1330 Nearest Common Ancestors LCA题解

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19728   Accept ...

  3. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  4. POJ 1330 Nearest Common Ancestors 倍增算法的LCA

    POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...

  5. POJ 1330 Nearest Common Ancestors(Targin求LCA)

    传送门 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26612   Ac ...

  6. POJ - 1330 Nearest Common Ancestors(基础LCA)

    POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %l ...

  7. pku 1330 Nearest Common Ancestors LCA离线

    pku 1330 Nearest Common Ancestors 题目链接: http://poj.org/problem?id=1330 题目大意: 给定一棵树的边关系,注意是有向边,因为这个WA ...

  8. poj 1330 Nearest Common Ancestors lca 在线rmq

    Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer scienc ...

  9. poj 1330 Nearest Common Ancestors(LCA 基于二分搜索+st&rmq的LCA)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30147   Accept ...

随机推荐

  1. 题解 P4302 【[SCOI2003]字符串折叠】

    讲讲我的做法 题目大意:对一个字符串进行折叠是它长度最小 看一眼数据范围:哇!字符串长度不超过100!这是一道省选题,不可能给你太宽裕的时限,所以,题目基本暗示你要用\(n^{3}\)多一些的算法复杂 ...

  2. Spring05——Spring 如何实现事务管理

    在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识 ...

  3. 基于arduino、百度云、采用django、redis鱼缸在线监控

    大家好,今天我给大家分享一下之前做的一个鱼缸远程监控的案例,希望有人喜欢 首先给大家看一下结构框架,由于我之前买的arduino开发板不带wifi功能,所有是通过pc机转发一下上的百度云,最近我刚购买 ...

  4. 分享一个超级好用的SM图床

    分享一个超级好用的SM图床 ​ 大家都知道我是一个喜欢sm Markdown的人,但是Markdown有个很不方便的地方,就是图片的插入,一般用Markdown编辑器(我用的是Typora)直接插入图 ...

  5. 2020年最新版Web前端学习路线图-前端小白入门必读-pink老师推荐

    Hello,大家好,相信很多学习前端的小伙伴,会有很多的疑惑: 我要学习那些技术? 我要到哪里去学习这些技术呢? 学习这些技术的目的对就业有什么帮助呢? 我学到什么程度可以胜任工作? ... 这里,p ...

  6. vue+cordova实现退出app效果

    //vue钩子函数created方法中添加监听等待设备API库加载好 created(){ var that = this; document.addEventListener("devic ...

  7. ScheduledThreadPoolExecutor之remove方法

    之前用定时任务的线程池,设置了个任务,但是突然今天产品说,某些个操作需要中断某些任务(如果任务还没有执行),使其不能再到点执行了.于是查了API果然有这样一个方法. 一看API,需要移除的是一个Run ...

  8. jmeter发送Query String Parameters格式参数报错

    当发起一次GET请求时,参数会以url string的形式进行传递.即?后的字符串则为其请求参数,并以&作为分隔符 当参数为json格式时,这时需要勾选编码,否则会报错

  9. 感动,我终于学会了Java对数组求和

    前言 看到题目是不是有点疑问:你确定你没搞错?!数组求和???遍历一遍累加起来不就可以了吗??? 是的,你说的都对,都听你的,但是我说的就是数组求和,并且我也确实是刚刚学会.╮(╯▽╰)╭ 继续看下去 ...

  10. Thinkphp getLastSql函数用法

    如何判断一个更新操作是否成功: $Model = D('Blog'); $data['id'] = 10; $data['name'] = 'update name'; $result = $Mode ...