Nearest Common Ancestors(最近公共祖先)
题目描述
有根树是一个在计算机科学和工程学中众所周知的数据结构。如下图所示的例子:
在上图,每个结点用1-16中的一个整数标记。结点8是这棵树的根。
一个结点x是一个结点y的祖先当且仅当结点x是在根和结点y的路径上。例如,结点4是结点16的祖先,结点10也是结点16的祖先。实际上,结点8,4和12都是结点16的祖先。记住每个结点都是它自己的祖先。结点8,4,6和7都是结点7的祖先。
一个结点x被称做结点y和z的公共祖先当且仅当x都是y和z的祖先。因此,结点8 和4是结点16和7的公共祖先。
一个结点x被称做结点y和z的最近公共祖先当且仅当x是y和z的一个公共祖先且在y和z的所有公共祖先中是最近的。所以,结点16和7的最近公共祖先是结点4,因为结点4比结点8更接近结点16和7。
在其它例子中,结点2和3的最近公共祖先结点10,结点6和13的最近公共祖先是结点8,结点4和12的最近公共祖先是结点4。在最后的一个例子中,如果y是z的一个祖先,那么y和z的最近公共祖先是y。
写一个程序找出在一棵树中两个不同结点的最近公共祖先。
输入输出格式
输入格式:
输入包括T组数据。第一行是一个整数T。
对每组数据,第一行是一个整数N,表示这棵树的结点数,其中2<=N<=10,000。
这些结点标记为1,2,…,N。
接下来的N-1行包括一对整数,代表一条边,第一个数是第二个数的父亲。
保证N个结点恰好有N-1条边。
最后的一行包括两个不同的整数,表示要求最近公共祖先的两个不同结点
输出格式:
对每组数据输出一行,包括一个表示所求的两个不同结点的最近公共祖先的整数
输入输出样例
输入样例:
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
输出样例:
4
3
Code 代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
long long n,t,i,j,x,y,m,r,d[11000],f[11000],p[50],st[11000][30];
vector<long long> e[11000];
void dfs(long long fa)
{
long long i;
for(i=1;i<30;i++)
st[fa][