Nearest Common Ancestors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 14902   Accepted: 7963

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
 /* ***********************************************
Author :kuangbin
Created Time :2013-9-5 0:09:55
File Name :F:\2013ACM练习\专题学习\LCA\POJ1330.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*
* LCA (POJ 1330)
* 在线算法 DFS + ST
*/
const int MAXN = ;
int rmq[*MAXN];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
int mm[*MAXN];
int dp[*MAXN][];//最小值对应的下标
void init(int n)
{
mm[] = -;
for(int i = ;i <= n;i++)
{
mm[i] = ((i&(i-)) == )?mm[i-]+:mm[i-];
dp[i][] = i;
}
for(int j = ; j <= mm[n];j++)
for(int i = ; i + (<<j) - <= n; i++)
dp[i][j] = rmq[dp[i][j-]] < rmq[dp[i+(<<(j-))][j-]]?dp[i][j-]:dp[i+(<<(j-))][j-];
}
int query(int a,int b)//查询[a,b]之间最小值的下标
{
if(a > b)swap(a,b);
int k = mm[b-a+];
return rmq[dp[a][k]] <= rmq[dp[b-(<<k)+][k]]?dp[a][k]:dp[b-(<<k)+][k];
}
};
//边的结构体定义
struct Edge
{
int to,next;
};
Edge edge[MAXN*];
int tot,head[MAXN]; int F[MAXN*];//欧拉序列,就是dfs遍历的顺序,长度为2*n-1,下标从1开始
int P[MAXN];//P[i]表示点i在F中第一次出现的位置
int cnt; ST st;
void init()
{
tot = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v)//加边,无向边需要加两次
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u,int pre,int dep)
{
F[++cnt] = u;
rmq[cnt] = dep;
P[u] = cnt;
for(int i = head[u];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(v == pre)continue;
dfs(v,u,dep+);
F[++cnt] = u;
rmq[cnt] = dep;
}
}
void LCA_init(int root,int node_num)//查询LCA前的初始化
{
cnt = ;
dfs(root,root,);
st.init(*node_num-);
}
int query_lca(int u,int v)//查询u,v的lca编号
{
return F[st.query(P[u],P[v])];
}
bool flag[MAXN];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int N;
int u,v;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
init();
memset(flag,false,sizeof(flag));
for(int i = ; i < N;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
flag[v] = true;
}
int root;
for(int i = ; i <= N;i++)
if(!flag[i])
{
root = i;
break;
}
LCA_init(root,N);
scanf("%d%d",&u,&v);
printf("%d\n",query_lca(u,v));
}
return ;
}

POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)的更多相关文章

  1. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

  2. POJ 1330 Nearest Common Ancestors (dfs+ST在线算法)

    详细讲解见:https://blog.csdn.net/liangzhaoyang1/article/details/52549822 zz:https://www.cnblogs.com/kuang ...

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

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

  4. poj 1330 Nearest Common Ancestors lca 在线rmq

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

  5. POJ 1330 Nearest Common Ancestors LCA题解

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

  6. poj 1330 Nearest Common Ancestors LCA

    题目链接:http://poj.org/problem?id=1330 A rooted tree is a well-known data structure in computer science ...

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

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

  8. POJ 1330 Nearest Common Ancestors(LCA模板)

    给定一棵树求任意两个节点的公共祖先 tarjan离线求LCA思想是,先把所有的查询保存起来,然后dfs一遍树的时候在判断.如果当前节点是要求的两个节点当中的一个,那么再判断另外一个是否已经访问过,如果 ...

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

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

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

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

随机推荐

  1. scala tuple中的syntactic sugar

    List[Tuple2[String, Int]] // Base List[(String, Int)] // Syntactic sugar List[Tuple3[String, Float, ...

  2. ArcMap2SLD使用

    1.首先打开ArcMap,加载一副mxd地图: 2.打开ArcGIS2SLD,如下图所示: 3.选择样式文件的保存形式,一副mxd地图可能有多个图层,选中In Separate Dateien/In ...

  3. 【前端vue开发】vue子调父 $emit (把子组件的数据传给父组件)

    ps:App.vue 父组件 Hello.vue 子组件 <!--App.vue :--> <template> <div id="app"> ...

  4. 基于vue配置axios

    转载地址:https://juejin.im/post/5a02a898f265da43052e0c85 1.背景 在项目开发中ajax请求是必不可缺少 一部分ajax请求不需要loading或则请求 ...

  5. java基础42 File类的构造函数及其方法

    本文知识点(目录): 1.IO流(Input Output)    2.IO流技术的运用场景    3.File类的构造函数(方法)    4.File类的一些常用方法    5.实例(解析File类 ...

  6. 洛谷P3811乘法逆元

    传送门 线性递推 #include <iostream> #include <cstdio> #include <cstring> #include <alg ...

  7. javaweb作业一

    作业:Http全称叫什么?有什么特点?端口号是多少?超文本传输协议:(1)遵循请求/响应模型(2)http协议是一种无状态协议,请求/响应完成后,连接会断开.这时,服务器无法知道当前访问的用户是否是老 ...

  8. (二)Jsoup 查找 DOM 元素

    第一节: Jsoup 查找 DOM 元素 getElementById(String id) 根据 id 来查询 DOM getElementsByTag(String tagName) 根据 tag ...

  9. 超简单的java爬虫

    最简单的爬虫,不需要设定代理服务器,不需要设定cookie,不需要http连接池,使用httpget方法,只是为了获取html代码... 好吧,满足这个要求的爬虫应该是最基本的爬虫了.当然这也是做复杂 ...

  10. hmm学习笔记(二)

    学习hmm近一周的时间,做个总结. 参考  李航的<统计学习方法>第9章,第10章 本文包含: 1.hmm模型 2.前向后向算法 3.Baum-Welch算法 4.维特比算法 1.hmm模 ...