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

LCA模板套上去就好了

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <iomanip>
#include<cmath>
#include<float.h>
#include<string.h>
#include<algorithm>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define pf printf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#include<vector>
#include<queue>
#include<map>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
const ll mod=1e9+100;
const double eps=1e-8;
using namespace std;
const double pi=acos(-1.0);
const int inf=0xfffffff;
const int N = 1010;
int rmq[2*N];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
int mm[2*N];
int dp[2*N][20];//最小值对应的下标
void init(int n)
{
mm[0] = -1;
for(int i = 1;i <= n;i++)
{
mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
dp[i][0] = i;
}
for(int j = 1; j <= mm[n];j++)
for(int i = 1; i + (1<<j) - 1 <= n; i++)
dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
}
int query(int a,int b)//查询[a,b]之间最小值的下标
{
if(a > b) swap(a,b);
int k = mm[b-a+1];
return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k];
}
};
//边的结构体定义
struct Edge
{
int to,next;
};
Edge edge[N*2];
int tot,head[N]; int F[N*2];//欧拉序列,就是dfs遍历的顺序,长度为2*n-1,下标从1开始
int P[N];//P[i]表示点i在F中第一次出现的位置
int cnt; ST st;
void init()
{
tot = 0;
memset(head,-1,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 != -1;i = edge[i].next)
{
int v = edge[i].to;
if(v == pre)continue;
dfs(v,u,dep+1);
F[++cnt] = u;
rmq[cnt] = dep;
}
}
void LCA_init(int root,int node_num)//查询LCA前的初始化
{
cnt = 0;
dfs(root,root,0);
st.init(2*node_num-1);
}
int query_lca(int u,int v)//查询u,v的lca编号
{
return F[st.query(P[u],P[v])];
}
bool root[N];
int main()
{
int n,m,num,v,u;
while(~scff(n,m))//n个点,m个查询点
{
init();
mm(sum,0);
mm(root,true);
rep(i,1,n)
{
sf("%d %d",&u,&v);
addedge(u,v);
addedge(v,u);
root[v]=false;
}
int temp;
rep(i,1,n+1)
{
if(root[i])
{
temp=i;break;
}
}
LCA_init(temp,n);
while(m--)
{
while(getchar()!='(') ;
scanf("%d%d",&u,&v);
while(getchar()!=')') ;
sum[query_lca(u,v)]++;
}
rep(i,1,n+1)
{
if(sum[i])
pf("%d:%d\n",i,sum[i]);
}
}
return 0;
}

D - Nearest Common Ancestors的更多相关文章

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

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

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

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

  3. POJ 1330 Nearest Common Ancestors

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

  4. POJ1330 Nearest Common Ancestors

      Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24587   Acce ...

  5. POJ 1330 Nearest Common Ancestors(Tree)

    题目:Nearest Common Ancestors 根据输入建立树,然后求2个结点的最近共同祖先. 注意几点: (1)记录每个结点的父亲,比较层级时要用: (2)记录层级: (3)记录每个结点的孩 ...

  6. 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)

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

  7. POJ 1330 Nearest Common Ancestors LCA题解

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

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

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

  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. pku 1330 Nearest Common Ancestors LCA离线

    pku 1330 Nearest Common Ancestors 题目链接: http://poj.org/problem?id=1330 题目大意: 给定一棵树的边关系,注意是有向边,因为这个WA ...

随机推荐

  1. Hibernate(6)关联关系_单向n对1

    1.单向 n-1 关联只需从 n 的一端可以访问 1 的一端 2.实体类 n端:Order.java public class Order { private Integer orderId; pri ...

  2. 发票打印不全不完整的解决方案(Win10)

    发票不管怎么设置,不是二维码缺少一点,就是金额小数点后边的数字显示不全 具体原因是打印机默认纸张上A4,实际发票纸张要比A4宽度宽一点点 原来写过一篇程序方便的打印票据的控制<终于部分解决了.N ...

  3. AssemblyInfo.cs文件详解

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq395537505/article/details/49661555 一.前言 .net工程的Pr ...

  4. SOFABolt 源码分析

    SOFABolt 是一个轻量级.高性能.易用的远程通信框架,基于netty4.1,由蚂蚁金服开源. 本系列博客会分析 SOFABolt 的使用姿势,设计方案及详细的源码解析.后续还会分析 SOFABo ...

  5. Thymeleaf-语法整理

    Thymeleaf其他案例看其他网站 http://www.cnblogs.com/hjwublog/p/5051732.html http://blog.csdn.net/u012706811/ar ...

  6. Xcode10.1 import头文件无法索引

    如下路径,修改设置 Xcode --> File --> Workspace Settings --> Build System --> Legacy Build System

  7. 怎么样加快JavaScript加载和执行效率

    概览 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器在下载 ...

  8. vue2.0 技巧汇总

    /** * Created by */ export default { trim: (str) => { //删除左右两端的空格 return str.replace(/(^\s*)|(\s* ...

  9. Halcon 彩色图片通道分割处理

    1.RGB通道:R红色,G绿色,B蓝色:R.G.B各占一个字节,取值范围在0—255:可代表的颜色数256*256*256==2^24 黑色区域是:R=G=B=0;   白色区域是:R=G=B=255 ...

  10. Android开发怎么让自己的APP UI漂亮、大方(规范篇一)

    首先,笔者是站立在开发者的角度来看UI设计的,欢迎专业人士提供指导,不多说,来看怎么把UI设计和开发高效结合起来~ 一.约定APP开发中的一些规则 1.大部分图标满足HDPI(高清)即可,比如:大众点 ...