描述:给出一棵有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[N]; 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 ",LCA); } } return 0; }