#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define N 100010
#define bug(a) cout<<a<<"******"<<endl;
int ok;
int fa[N],node[N],vis[N],anc[N],ans;
struct node
{
int to;
int next;
}edge[N<<2];
int head[N],cnt;
int que[2];
void init()
{
memset(head,-1,sizeof(head));
memset(node,0,sizeof(node));
memset(vis,0,sizeof(vis));
cnt = 0;
}
void add( int u , int v )
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
int find(int x)
{
if(fa[x] != x)
return fa[x] = find(fa[x]);
return x;
}
void uni(int u,int v)
{
int x = find(u);
int y = find(v);
if( x != y )
fa[x] = y;
}
void LCA(int u)
{
int i,j,v;
vis[u] = 1;
for ( i = head[u] ; i != -1 ; i = edge[i].next )
{
v = edge[i].to;
if(vis[v])
continue;
LCA(v);
uni(u,v);
anc[find(v)] = u;
}
if( u == que[0] && vis[que[1]] )
{
ans = anc[find(que[1])];
return ;
}
if( u == que[1] && vis[que[0]])
{
ans = anc[find(que[0])];
return ;
}
}
int main()
{
int i,j,T,n,u,v;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for( i = 0 ; i <= n ; i ++ )
fa[i] = i ;
for ( i = 0 ; i < n - 1 ; i ++ )
{
scanf("%d%d",&u,&v);
add(u,v);
node[v] ++;
}
scanf("%d%d",&que[0],&que[1]);
for ( i = 1 ; i <= n ; i ++ )
{
if(!node[i])
{
LCA(i);
printf("%d\n",ans);
break;
}
}
}
return 0 ;
}
题目大意:
输入T组测试数据
输入N
接下来N-1行代表了一条边
输入A,B,其中A为B的父节点
第N行为询问,问该两点的最近公共祖先