版权声明:本人小白,有错误之处恳请指出,感激不尽;欢迎转载 https://blog.csdn.net/stone_fall/article/details/88756472
最近公共祖先
题目描述
给出一棵有N个节点的有根树TREE(根的编号为1),对于每组查询,请输出树上节点u和v的最近公共祖先。
最近公共祖先:对于有向树TREE的两个结点u,v。最近公共祖先LCA(TREE u,v)表示一个节点x,满足x是u、v的祖先且x的深度尽可能大。
输入格式
输入数据第一行是一个整数T(1<=T<=100),表示测试数据的组数。
对于每组测试数据:
第一行是一个正整数N(1<=N<=100),表示树上有N个节点。
接下来N-1行,每行两个整数u,v(1<=u,v<=N),表示节点u是v的父节点。
接下来一行是一个整数M(1<=M<=1000),表示查询的数量。
接下来M行,每行两个整数u,v(11<=u,v<=N),表示查询节点u和节点v的最近公共祖先。
输出格式
对于每个查询,输出一个整数,表示最近公共祖先的编号,
输入样例
2
3
1 2
1 3
1
2 3
4
1 2
1 3
3 4
2
2 3
3 4
输出样例
1
1
3
AC代码
#include<bits/stdc++.h>
#define MAXN 110
#define For(i,start,end) for(int i=start;i<end;i++)
using namespace std;
int tree[MAXN];
int main()
{
int t,n,son,father,m,u,v;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(tree,0,sizeof tree);//0为没有父节点,1为根
For(i,0,n-1){
scanf("%d%d",&father,&son);
tree[son]=father;
}
scanf("%d",&m);
while(m--){
scanf("%d%d",&u,&v);
vector<int> u_fa;
vector<int> v_fa;
u_fa.push_back(u);
while(tree[u]!=0){
u=tree[u];
u_fa.push_back(u);
}
v_fa.push_back(v);
while(tree[v]!=0){
v=tree[v];
v_fa.push_back(v);
}
int ans=1;
for(int i=u_fa.size()-1,j=v_fa.size()-1;i>=0&&j>=0;i--,j--){
if(u_fa[i]==v_fa[j]){
ans = u_fa[i];
}
else{
break;
}
}
printf("%d\n",ans);
}
}
return 0;
}