您的位置:首页 > 其它

最近公共祖先

2018-03-25 21:44 246 查看

描述:给出一棵有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的最近公共祖先。

#include <iostream>
#include<stack>
#define N 500
using namespace std;

struct Set{
int root
;
int setSize;
void initSet(int setSize){
for(int i=0;i<=setSize;i++)
root[i]=-1;
}
int findRoot(int x,stack<int> &s){//该点所有祖先放入栈中
while(root[x]!=-1){
s.push(x);
x=root[x];
}
s.push(x);
return x;
}
};

int main()
{
int t;
Set set;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
set.initSet(n);//初始化
int u,v;
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
set.root[v]=u;
}
int m;
scanf("%d",&m);
while(m--){
stack<int> fa1,fa2;
while(!fa1.empty())//清空
fa1.pop();
while(!fa2.empty())
fa2.pop();
scanf("%d%d",&u,&v);
set.findRoot(u,fa1);//fa1中放所有u的祖先
set.findRoot(v,fa2);//fa2中放所有v的组线
int size1=fa1.size();//求fa1的大小
int size2=fa2.size();//求fa2的大小
//把祖先数目先变成一样多,这样使至少祖先都在同一层
if(size1>size2){
while(size1>size2){
fa1.pop();
size1--;
}
}
else if(size2>size1){
while(size1<size2){
fa2.pop();
size2--;
}
}
int root1,root2,LCA;
while(!fa1.empty() && !fa2.empty()){
root1=fa1.top();
root2=fa2.top();
fa1.pop();
fa2.pop();
if(root1==root2){//找到最近祖先
LCA=root1;
break;
}
}
printf("%d\n",LCA);
}
}
return 0;
}

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: