求最近公共祖先。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e4 + 10;
int father[maxn], ans[maxn][maxn];
bool vis[maxn];
int flag[maxn];
vector<int> que[maxn];
int N, M;
int T;
struct Edge
{
int to, next;
}edge[maxn];
int tot, head[maxn];
void add(int a, int b)
{
edge[tot].to = b; edge[tot].next = head[a]; head[a] = tot++;
}
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= N; i++)
father[i] = i;
}
int findfa(int x)
{
while(x != father[x])
x = father[x];
return x;
}
void LCA(int k)
{
int j, v;
for(j = head[k]; j != -1; j = edge[j].next)
{
v = edge[j].to;
if(!vis[v])
{
LCA(v);
father[v] = k;
}
}
vis[k] = true;
int sz = que[k].size();
int t;
for(int i = 0; i < sz; i++)
{
t = que[k][i];
if(vis[t])
{
int fa = findfa(t);
ans[k][t] = ans[t][k] = fa;
return;
}
}
}
int main()
{
cin >> T;
while(T--)
{
cin >> N;
init(); //init函数里用到了N,注意位置!
memset(flag, 0, sizeof(flag));
for(int i = 1; i <= N; i++)
que[i].clear();
int a, b;
for(int i = 1; i <= N - 1; i++)
{
scanf("%d%d", &a, &b);
add(a, b);
flag[b]++;
}
int p, q;
cin >> p >> q;
que[p].push_back(q);
que[q].push_back(p);
for(int i = 1; i <= N; i++)
{
if(!flag[i])
LCA(i);
cout << ans[p][q] << endl;
}
return 0;
}