本题是LCA问题的模板题,用tarjan算法来解决。
#include<iostream>
#include<vector>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn=10003;
vector<int> son[maxn],que[maxn];
int pre[maxn],ance[maxn];
bool vs[maxn];
int findx(int a)
{
return (a==pre[a])?a:(pre[a]=findx(pre[a]));
}
void join(int a,int b)
{
int fa=findx(a);
int fb=findx(b);
if(fa!=fb)
pre[fa]=fb;
}
void LCA(int root)
{
ance[root]=root;
for(int i=0;i<son[root].size();i++)
{
LCA(son[root][i]);
join(root,son[root][i]);
ance[findx(son[root][i])]=root;
}
vs[root]=true;
for(int i=0;i<que[root].size();i++)
{
if(vs[que[root][i]])
{
printf("%d\n",ance[findx(que[root][i])]);
return;
}
}
}
int main()
{
int t,n,from,to,head;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(ance,0,sizeof(pre));
memset(vs,0,sizeof(vs));
for(int i=1;i<=n;i++)
{
pre[i]=i;
son[i].clear();
que[i].clear();
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&from,&to);
son[from].push_back(to);
vs[to]=true;
}
for(head=1;head<=n;head++)
if(vs[head]==false)
break;
int a,b;
scanf("%d%d",&a,&b);
que[a].push_back(b);
que[b].push_back(a);
memset(vs,0,sizeof(vs));
LCA(head);
}
return 0;
}