Nearest Common Ancestors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 24587   Accepted: 12779

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.

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

Source

LCA(最近公共祖先)

先找到树根,之后倍增处理出每个点的祖先结点,然后同时上溯即可。

 //lca
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int mxn=;
int n;
vector<int> e[mxn];
int fa[mxn][];
int dep[mxn];
int in[mxn];
void add_edge(int u,int v){
e[u].push_back(v);
in[v]++;
}
void dfs(int u){//求点深度,倍增算祖先结点fa
for(int i=;i<e[u].size();i++){
int v=e[u][i];
fa[v][]=u;
dep[v]=dep[u]+;
for(int j=;(<<j)<=dep[v];j++){
fa[v][j]=fa[fa[v][j-]][j-];
}
dfs(v);
}
return;
}
int lca(int a,int b){
if(dep[a]<dep[b])swap(a,b);//(处理深度更大的那个)
for(int i=;i!=-;i--)//从高位开始试。(其实从低开始也一样?)
if(dep[a]>=dep[b]+(<<i))a=fa[a][i];//此步结束后,a和b查找到的深度相同
if(a==b)return a;
for(int i=;i!=-;i--)//共同上溯
if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return fa[a][];
}
int main(){
int T;
scanf("%d",&T);
int i,j;
while(T--){
memset(dep,,sizeof(dep));
memset(fa,,sizeof(fa));
memset(in,,sizeof(in));
scanf("%d",&n);
for(i=;i<=n;i++) e[i].clear();
int u,v;
for(i=;i<n;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
}
int root=;
for(i=;i<=n;i++)if(in[i]==){root=i;break;}//入度为0的那个点是根
dep[root]=;
fa[root][]=-;
dfs(root);
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
return ;
}

POJ1330 Nearest Common Ancestors的更多相关文章

  1. POJ1330 Nearest Common Ancestors(最近公共祖先)(tarjin)

    A - Nearest Common Ancestors Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld &am ...

  2. POJ1330 Nearest Common Ancestors (JAVA)

    经典LCA操作.. 贴AC代码 import java.lang.reflect.Array; import java.util.*; public class POJ1330 { // 并查集部分 ...

  3. [POJ1330]Nearest Common Ancestors(LCA, 离线tarjan)

    题目链接:http://poj.org/problem?id=1330 题意就是求一组最近公共祖先,昨晚学了离线tarjan,今天来实现一下. 个人感觉tarjan算法是利用了dfs序和节点深度的关系 ...

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

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

  5. POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)

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

  6. JDOJ 3055: Nearest Common Ancestors

    JDOJ 3055: Nearest Common Ancestors JDOJ传送门 Description 给定N个节点的一棵树,有K次查询,每次查询a和b的最近公共祖先. 样例中的16和7的公共 ...

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

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

  8. [最近公共祖先] POJ 1330 Nearest Common Ancestors

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

  9. POJ 1330 Nearest Common Ancestors

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

随机推荐

  1. Jenkins遇到问题一:jenkins配置权限不对导致无法登陆或者空白页面解决办法

    找到.jenkins/config.xml文件:替换为:1.<authorizationStrategy class="hudson.security.AuthorizationStr ...

  2. css 字体不撑开默认块级元素问题

    问题原因是行高的元素没有随字体大小而改变,设置line-hight属性和字体同时变换

  3. iOS下使用SHA1WithRSA算法加签源码

    首先了解一下几个相关概念,以方便后面遇到的问题的解决: RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数 ...

  4. FMDB 使用方法

    优秀的第三方库,README 也是很优秀的,理解了 README,会对使用带来很多便利. ARC 和 MRC 项目中使用 ARC 还是 MRC,对使用 FMDB 都没有任何影响,FMDB 会在编译项目 ...

  5. poj1144

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12521   Accepted: 5760 Descript ...

  6. 动态执行SQL语句

    在实际制作过程中,需要动态的拼接SQL语句然后执行.具体代码如下: declare @columnName varchar(20),@tempName varchar(20) select @temp ...

  7. Ubuntu下类似于Total Commander的两个工具

    Total Commander for linux Is there a Linux version? Unfortunately not. Because of problems with port ...

  8. js对象的两种写法

    <script>     //定义一个对象,提供对应的方法或者属性     var s = {         sd1: function () { },         sd2: fun ...

  9. 自编基于jQuery实现分页插件

    $(function(){ }); /** * @params dataUrl:请求数据url地址 * @params countUrl:请求数据总数url地址 * @params pageSize: ...

  10. Java学习笔记(二十)——Java 散列表_算法内容

    [前面的话] 周末,本来打算找人去玩,结果没找到,所以我只好有学习了. 为什么会学习散列表,因为要使用HashMap?因为在做项目的时候,在服务器和客户端需要传输DTO,而传输的属性是动态增加的,所以 ...