题意:给出一棵树上根节点与子节点的关系,求两节点的最近公共祖先
这题虽然是比较裸的Tarjin,但是我WA到死!。。刚开始我用邻接表存储边的关系和询问关系,一直WA,我以为用邻接表的过程中出了错误,所以注释掉,改用vector来存储,后面OLE!唉~AC之路真艰难,,,后面一个一个的检查,实在找不出,叫龙帮我看了下,后面我发现了一个初始化问题,然后改了一交A!。。马上我就跑到原来用邻接表写的那个代码,改了改,一交RE!泪喷~把数组开大A!我可真是幸福呀。。。
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define lson l,mid,num<<1
#define rson mid+1,r,num<<1|1
using namespace std;
const int M=905;
int in[M],ans[M],fa[M],ance[M],head[M],head2[M];
int e,e2,vis[M];
struct node
{
int v,next;
} edge[2*M];
struct node1
{
int v,next;
} edge2[M*M];//这个好坑爹
void add(int u,int v)
{
edge[e].v=v;
edge[e].next=head[u];
head[u]=e++;
}
void add2(int u,int v)
{
edge2[e2].v=v;
edge2[e2].next=head2[u];
head2[u]=e2++;
edge2[e2].v=u;
edge2[e2].next=head2[v];
head2[v]=e2++;
}
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void Union(int u,int v)
{
fa[find(v)]=u;
}
void tarjin(int u)
{
ance[u]=u;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
if(!vis[edge[i].v])
{
tarjin(edge[i].v);
Union(u,edge[i].v);
ance[find(u)]=u;
}
}
vis[u]=1;
for(int i=head2[u]; i!=-1; i=edge2[i].next)
{
int v=edge2[i].v;
if(vis[v])
{
ans[find(v)]++;
}
}
}
int main()
{
int n,v,m,q,u;
while(scanf("%d",&n)!=EOF)
{
memset(head,-1,sizeof(head));
memset(head2,-1,sizeof(head2));
for(int i=1; i<=n; i++)
{
ance[i]=0;
in[i]=0;
ans[i]=vis[i]=0;//vis[i]=0!!!!
fa[i]=i;
}
e=e2=0;
for(int i=1; i<=n; i++)
{
scanf("%d:(%d)",&u,&m);
for(int i=0; i<m; i++)
{
scanf("%d",&v);
add(u,v);
in[v]=1;
}
}
int x,y;
scanf("%d",&q);
while(q--)
{
while(getchar()!='(');
scanf("%d %d",&x,&y);
while(getchar()!=')');
add2(x,y);
}
for(int i=1; i<=n; i++)
{
if(in[i]==0)
{
tarjin(i);
break;
}
}
for(int i=1; i<=n; i++)
{
if(ans[i]>0)
{
printf("%d:%d\n",i,ans[i]);
}
}
}
return 0;
}