Nearest Common Ancestors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 23795   Accepted: 12386

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

下面这段模板代码引自某位大神的博客 http://www.cppblog.com/menjitianya/archive/2015/12/10/212447.html

void LCA_Tarjan(int u) { 

        make_set(u);                               // 注释1
        ancestor[ find(u) ] = u;                   // 注释2
        for(int i = 0; i < edge[u].size(); i++) {  // 注释3
            int v = edge[u][i].v; 
            LCA_Tarjan(v);                         // 注释4
            merge(u, v);                           // 注释5
            ancestor[ find(u) ] = u;               // 注释6
        }
        colors[u] = 1;                             // 注释7
        for(int i = 0; i < lcaInfo[u].size(); i++) {
            int v = lcaInfo[u][i].v;
            if(colors[v]) {                        // 注释8
                lcaDataAns[ lcaInfo[u][i].idx ].lca = ancestor[ find(v) ];
            }
        }
    }
    注释1:创建一个集合,集合中只有一个元素u,即{ u }
    注释2:因为u所在集合只有一个元素,所以也可以写成ancestor[u] = u
    注释3:edge[u][0...size-1]存储的是u的直接子结点
    注释4:递归计算u的所有直接子结点v
    注释5:回溯的时候进行集合合并,将以v为根的子树和u所在集合进行合并
    注释6:对合并完的集合设置集合对应子树的根结点,find(u)为该集合的代表元
    注释7:u为根的子树访问完毕,设置结点颜色
    注释8:枚举所有和u相关的询问(u, v),如果以v为根的子树已经访问过,那么ancestor[find(v)]肯定已经计算出来,并且必定是u和v的LCA
 
对于注释8的for循环,这个题只查询两个点,没必要用另外一个邻接表了
 
//题意:t组测试用例,输入n,接下来输入n-1条边 组成一棵树,第n组数据代表询问a b之间最近公共祖先
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
const int MAX = ;
vector<int> mp[MAX];
int father[MAX];
int indegree[MAX]; ///入度为0的就是根节点
int _rank[MAX]; ///利用启发式合并防止树成链
int vis[MAX];
int ances[MAX];
int A,B;
void init(int n){
for(int i=;i<=n;i++){
ances[i]=;
vis[i]=;
_rank[i] = ;
indegree[i]=;
father[i] = i;
mp[i].clear();
}
}
int _find(int x){
if(x==father[x]) return x;
return father[x] = _find(father[x]);
}
void _union(int a,int b){
int x = _find(a);
int y = _find(b);
father[x]=y;
}
int Tarjan(int u)
{
for (int i=;i<mp[u].size();i++)
{
Tarjan(mp[u][i]);
_union(u,mp[u][i]);
ances[_find(u)]=u;
}
vis[u]=;
if (A==u && vis[B]) printf("%d\n",ances[_find(B)]);
else if (B==u && vis[A]) printf("%d\n",ances[_find(A)]);
return ;
}
int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--){
int n;
scanf("%d",&n);
init(n);
int a,b;
for(int i=;i<n;i++){
scanf("%d%d",&a,&b);
mp[a].push_back(b);
indegree[b]++;
}
scanf("%d%d",&A,&B);
for(int i=;i<=n;i++){
if(indegree[i]==){
Tarjan(i);
break;
}
}
}
return ;
}

poj 1330(初探LCA)的更多相关文章

  1. POJ 1330 (LCA)

    http://poj.org/problem?id=1330 题意:给出一个图,求两个点的最近公共祖先. sl :水题,贴个模板试试代码.本来是再敲HDU4757的中间发现要用LCA,  操蛋只好用这 ...

  2. POJ 1330(LCA/倍增法模板)

    链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: #inc ...

  3. poj 1330(RMQ&LCA入门题)

    传送门:Problem 1330 https://www.cnblogs.com/violet-acmer/p/9686774.html 参考资料: http://dongxicheng.org/st ...

  4. Nearest Common Ancestors POJ - 1330 (LCA)

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

  5. POJ 1330 Tarjan LCA、ST表(其实可以数组模拟)

    题意:给你一棵树,求两个点的最近公共祖先. 思路:因为只有一组询问,直接数组模拟好了. (写得比较乱) 原题请戳这里 #include <cstdio> #include <bits ...

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

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

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

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

  8. POJ.1330 Nearest Common Ancestors (LCA 倍增)

    POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...

  9. POJ 1330 Nearest Common Ancestors (LCA,倍增算法,在线算法)

    /* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 F ...

随机推荐

  1. 四道JavaScript面试题检测你的js基本功

    下面有四道简短的JavaScript小脚本,如果你能顺利预测脚本的运行结果,那么你的JavaScript基本功还是可以的.如果答错了,可以相应地去补一下缺漏的知识.反正也很简单,答错了只是说明你没了解 ...

  2. Magic FZU - 2280 无脑HASH暴力

    Kim is a magician, he can use n kinds of magic, number from 1 to n. We use string Si to describe mag ...

  3. DOM学习控件定位和案例

    Dom中有多种定位属性,下面是一个简单案例 <html><!--制作一个会跟着鼠标走的图像,还有控件定位的案例--> <head> <title>doc ...

  4. android极光推送初步了解

    推送可以及时,主动的与用户发起交互 (1)继承jar包,照示例AndroidManifest.xml添加. (2)自定义MyApp继承自Application,在onCreate方法中调用JPushI ...

  5. 快速排序Quick sort

    快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归 ...

  6. WP8.1 Windows Phone 8.1开发:何如定义Pivot头部样式、定义Pivot头部颜色

    Windows Phone 8.1 ,如何自定义Pivot头部样式?用Pivot控件完成这样的效果. 网上找了好久,只找到了windows phone 8的解决方案. 终于一个大神给支了招,我觉得我有 ...

  7. SQL语句中的单引号处理以及模糊查询

    为了防止程序SQL语句错误以及SQL注入,单引号必须经过处理.有2种办法: 1.使用参数,比如SELECT * FROM yourTable WHERE name = @name; 在C#中使用Sql ...

  8. python数据处理课程笔记(一)

    一.numpy 1.numpy中所有元素必须是相同的类型 a=[1,2,3,4,'t'] #列表中有str类型,转换为ndarray时所有元素都转换为str类型 arr1=np.array(a) pr ...

  9. js中三种定义变量 const, var, let 的区别

    js中三种定义变量的方式const, var, let的区别 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 ...

  10. oracle 的number数据类型

    NUMBER类型细讲:Oracle number datatype 语法:NUMBER[(precision [, scale])]简称:precision --> p      scale   ...