# POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors （最近公共祖先LCA）

### Description

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.

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

4

3

## 解决思路

LCA还有一些细节的地方需要注意，具体请看代码（都用注释标记出来了）

## 代码

``````#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int maxN=10011;
const int inf=2147483647;

int n;
int root;
vector<int> E[maxN];
int Parent[maxN][25];
int Depth[maxN];
bool vis[maxN];

void LCA_init();
void dfs(int u);
int LCA(int a,int b);

int main()
{
int TT;
for (int ti=1;ti<=TT;ti++)
{
for (int i=1;i<=n;i++)
E[i].clear();
memset(vis,0,sizeof(vis));
for (int i=1;i<n;i++)
{
E[x].push_back(y);
vis[y]=1;
}
for (int i=1;i<=n;i++)
if (vis[i]==0)
root=i;
//cout<<root<<endl;
LCA_init();//LCA的初始化，即计算Depth和Parent数组
}
return 0;
}

{
int x=0;
int k=1;
char ch=getchar();
while (((ch>'9')||(ch<'0'))&&(ch!='-'))
ch=getchar();
if (ch=='-')
{
k=-1;
ch=getchar();
}
while ((ch<='9')&&(ch>='0'))
{
x=x*10+ch-48;
ch=getchar();
}
return x*k;
}

void LCA_init()
{
memset(Depth,0,sizeof(Depth));
Depth[root]=0;
memset(Parent,0,sizeof(Parent));
dfs(root);//首先用dfs计算出Depth和Parent[u][0]
int kk=0;
for (int j=1;j<=20;j++)//注意这里必须是j的循环在外面，i在里面，这是为了保证要计算某个值时它所需要的值已经计算出来了。
for (int i=1;i<=n;i++)
Parent[i][j]=Parent[Parent[i][j-1]][j-1];
/*for (int i=1;i<=n;i++)
{
for (int j=0;j<=kk;j++)
cout<<Parent[i][j]<<' ';
cout<<endl;
}
*/
}

void dfs(int u)
{
for (int i=0;i<E[u].size();i++)
{
int v=E[u][i];
Depth[v]=Depth[u]+1;
Parent[v][0]=u;
dfs(v);
}
return;
}

int LCA(int a,int b)
{
if (Depth[b]>Depth[a])//保证a的深度>=b的深度
swap(a,b);

for (int i=20;i>=0;i--)//把a提到与b高度一致
if ((Parent[a][i]!=0)&&(Depth[Parent[a][i]]>=Depth[b]))
a=Parent[a][i];
if (a==b)
return a;

for (int i=20;i>=0;i--)//把a和b同时向上提
if ((Parent[a][i]!=0)&&(Parent[b][i]!=0)&&(Parent[a][i]!=Parent[b][i]))
{
a=Parent[a][i];
b=Parent[b][i];
}
return Parent[a][0];注意返回值
}
``````

## POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors （最近公共祖先LCA）的更多相关文章

1. POJ 1470 Closest Common Ancestors（最近公共祖先 LCA）

POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...

2. POJ 1330 Nearest Common Ancestors 【最近公共祖先LCA算法+Tarjan离线算法】

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

3. POJ 1470 Closest Common Ancestors【近期公共祖先LCA】

版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013912596/article/details/35311489 题目链接:http://poj ...

4. [leetcode]236. Lowest Common Ancestor of a Binary Tree二叉树最近公共祖先

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. Accordi ...

5. 236. Lowest Common Ancestor of a Binary Tree（最低公共祖先，难理解）

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

6. LeetCode OJ：Lowest Common Ancestor of a Binary Tree（最近公共祖先）

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

7. POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客）

LCA问题的tarjan解法模板 LCA问题 详细 1.二叉搜索树上找两个节点LCA public int query(Node t, Node u, Node v) { int left = u.v ...

8. HDU 1330 Nearest Common Ancestors(求两个点的近期公共祖先)

题目链接:id=1330">传送门 在线算法: #include <iostream> #include <cstdio> #include <cstri ...

9. POJ 1470 Closest Common Ancestors （最近公共祖先LCA 的离线算法Tarjan）

Tarjan算法的详细介绍,请戳: http://www.cnblogs.com/chenxiwenruo/p/3529533.html #include <iostream> #incl ...

## 随机推荐

1. RTMP流媒体播放过程

RTMP协议规定:第一步,建立一个网络连接(NetConnection):客户端和服务端的基础连通关系 第二步:建立一个网络流(NetStream)发送多媒体的通道(只能建立一个网络连接,可以建立 ...

2. [转载]《民航科技》2012年4月专家论坛：罗喜伶《SWIM技术国际研究动态及对中国民航的借鉴意义》

专家介绍:罗喜伶,北京航空航天大学电子信息工程学院副教授,工学博士,硕士生导师,国家空管新航行系统技术重点实验室和协同式网络化空中交通管理系统研究教育部创新团队核心成员,民航空管广域信息系统专家组成员 ...

3. RPM卸载软件包

如何卸载rpm包 首先:通过  rpm -q <关键字> 可以查询到rpm包的名字 然后:调用 rpm -e <包的名字> 删除特定rpm包 如果遇到依赖,无法删除,使用 rp ...

4. java 多线程1

进程: 线程: 多线程: 假象:只是CPU在做快速的切换 多线程的好处: 1.解决了一个进程里面可以同时运行多个任务(执行路径) 2.提高资源利用率,而不是效率. 多线程的弊端: 1.降低了一个进程里 ...

5. 程序启动原理和UIApplication

iOS开发UI篇—程序启动原理和UIApplication   一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...

6. mysql修改编码

1.查看当前编码 2.设置utf8mb4编码(也可以是其他),修改my.cnf或my.ini

7. iOS设计模式之懒加载

一.为什么要懒加载? 答: iPhone设备内存有限,如果在程序在启动后就一次性加载将来会用到的所有资源,那么久可能会耗尽iOS设备的内存.这些资源例如大量的数据,图片,音频,过多的控件等. 二.懒加 ...

8. 搜索+剪枝——POJ 1011 Sticks

搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...

9. pyenv BUILD FAILED解决方法