一道模板题
讲解请看 https://blog.youkuaiyun.com/qq_41837216/article/details/83416270
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=1010;
vector<int>g[maxn];
int fa[maxn][11],d[maxn];
int n,m,root;
bool vis[maxn];
void init()
{
memset(fa,0,sizeof(fa));
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
}
void dfs(int u)
{
int i;
vis[u]=1;
for(i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v])
{
d[v]=d[u]+1;
dfs(v);
}
}
}
void bz()
{
int i,j;
for(j=1;j<=10;j++)
for(int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
}
int lca(int u,int v)
{
if(d[u]<d[v])
swap(u,v);
int dc=d[u]-d[v];
int i;
for(i=0;i<=10;i++)
{
if((1<<i)&dc)
u=fa[u][i];
}
if(u==v)
return u;
for(i=10;i>=0;i--)
{
if(fa[u][i]!=fa[v][i])
{
u=fa[u][i];
v=fa[v][i];
}
}
u=fa[u][0];
return u;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
init();
scanf("%d",&n);
for(int j=0;j<=n;j++)
g[j].clear();
for(int j=1;j<=n;j++)
{
scanf("%d",&m);
while(m--)
{
int a;
scanf("%d",&a);
g[j].push_back(a);
fa[a][0]=j;
if(fa[j][0]==0)
root=j;
}
}
d[root]=1;
dfs(root);
bz();
int k,x,y;
scanf("%d",&k);
printf("Case %d:\n",i);
while(k--)
{
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
}
return 0;
}