最近公共祖先的题目。第一个点不一定是跟。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=900+9;
int head[maxn],lon,qhead[maxn],qlon;
int ans[maxn],chk[maxn],f[maxn],in[maxn];
struct node
{
int next,to;
}e[maxn<<1],qe[2000000];
void edgeini()
{
memset(head,-1,sizeof(head));
memset(qhead,-1,sizeof(qhead));
qlon=-1;
lon=-1;
}
void edgemake(int from,int to,struct node e[],int &lon,int head[])
{
e[++lon].to=to;
e[lon].next=head[from];
head[from]=lon;
}
int find(int x)
{
if(f[x]!=x)
return(f[x]=find(f[x]));
return(f[x]);
}
void dfs(int t)
{
chk[t]++;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(!chk[u])
{
dfs(u);
f[u]=t;
}
}
for(int k=qhead[t];k!=-1;k=qe[k].next)
{
int u=qe[k].to;
if(chk[u]==2)
{
ans[find(u)]++;
}
}
chk[t]++;
}
int main()
{
int n,m,t;
// freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
edgeini();
memset(ans,0,sizeof(ans));
memset(in,0,sizeof(in));
for(int i=1,tmp,from,to;i<=n;i++)
{
scanf("%d",&from);
char c;
while(scanf("%c",&c),c!=':') ;
while(scanf("%c",&c),c!='(') ;
scanf("%d",&tmp);
while(scanf("%c",&c),c!=')') ;
for(int j=1;j<=tmp;j++)
{
scanf("%d",&to);
in[to]++;
edgemake(from,to,e,lon,head);
edgemake(to,from,e,lon,head);
}
}
scanf("%d",&m);
for(int i=1,from,to;i<=m;i++)
{
char c;
while(scanf("%c",&c),c!='(') ;
scanf("%d %d",&from,&to);
while(scanf("%c",&c),c!=')');
edgemake(from,to,qe,qlon,qhead);
edgemake(to,from,qe,qlon,qhead);
}
memset(chk,0,sizeof(chk));
for(int i=1;i<=n;i++)
{
f[i]=i;
if(in[i]==0)
t=i;
}
dfs(t);
for(int i=1;i<=n;i++)
if(ans[i])
printf("%d:%d\n",i,ans[i]);
}
return 0;
}