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. DOM通过ID或NAME获取值

    DOM通过ID或NAME获取值 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> &l ...

  2. lightoj 1282 && uva 11029

    Leading and Trailing lightoj 链接:http://lightoj.com/volume_showproblem.php?problem=1282 uva 链接:http:/ ...

  3. SQL Server 代理(已禁用代理 XP)

    sp_configure 'show advanced options', 1; GO RECONFIGURE WITH OVERRIDE; GO sp_configure 'Agent XPs', ...

  4. 你还在用notifyDataSetChanged?

    想到发这篇帖子是源于我的上一篇帖子#Testin杯#多线程断点续传后台下载 .帖子中讲述的项目使用了listView这个控件,而且自定义了adapter.在更新item的进度条时发现每次使用notif ...

  5. String.replaceAll()方法替换字符串中的反斜杠(\)

    replaceAll()方法实际是采用正则表达式的规则去匹配的. 在regex中"\\"表示一个"\",在java中一个"\"也要用&quo ...

  6. Redux Concepts

    Redux解决数据通信复杂问题. Store 存储数据的地方,一个应用只有一个Store. State Store对象包含所有数据. Action 一个对象,表示View的变化. Action Cre ...

  7. ionic@2.0 beta版本安装指南

    由于访问npm官方源下载ionic速度缓慢,淘宝提供了npm源,方便国内人士访问. 1.通过config命令 npm config set registry https://registry.npm. ...

  8. 【Dream Counting, 2006 Dec-数数的梦】数位dp

    题意:给定两个数,问区间[A,B]中0~9分别出现了多少次.A,B<=10^18 题解:应该是最裸的数位dp吧..一开始没有记忆化tle了TAT 我们可以求出区间[0,B]的,再减去区间[0,A ...

  9. bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍 ——中位数排序

    Description 经过多年的积蓄,农夫JOHN决定造一个新的牛舍.他知道所有N(2 <= N <= 10,000)头牛的吃草位置,所以他想把牛舍造在最方便的地方. 每一头牛吃草的位置 ...

  10. 剖析 golang 的25个关键字

    剖析 golang 的25个关键字 基本在所有语言当中,关键字都是不允许用于自定义的,在Golang中有25个关键字,图示如下: 下面我们逐个解析这25个关键字. var && con ...