SP14932 【LCA - Lowest Common Ancestor】

专业跟队形

唯一一个有$L^{A_{T^{E_X}}}$的

裸的$LCA$,我用的是$Tarjan~LCA$,注意两点相同特判

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
struct edge{
    int next,to;
}e[maxn],q[maxn<<1];
int n,m,s,head[maxn],cnt,ans[maxn],heads[maxn],f[maxn],cntc;
bool vis[maxn];
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
void add(int x,int y)
{
    e[++cnt].next=head[x];
    e[cnt].to=y;
    head[x]=cnt;
}
void adds(int x,int y)
{
    q[++cnt].next=heads[x];
    q[cnt].to=y;
    heads[x]=cnt;
}
void tarjan(int x,int pre)
{
    for(int v,i=head[x];i;i=e[i].next)
    {
        if((v=e[i].to)==pre)
            continue;
        tarjan(v=e[i].to,x);
        int f1=find(x),f2=find(v);
        if(f1!=f2)
            f[f2]=f1;
    }
    for(int i=heads[x];i;i=q[i].next)
        if(vis[q[i].to])
            ans[(i+1)>>1]=find(q[i].to);
    vis[x]=1;
}
int main()
{
    scanf("%d",&s);
    while(s--)
    {
        scanf("%d",&n);
        cnt=0;
        memset(head,0,sizeof(head));
        memset(heads,0,sizeof(heads));
        memset(vis,0,sizeof(vis));
        for(int x,num,i=1;i<=n;i++)
        {
            scanf("%d",&num);
            for(int j=1;j<=num;j++)
            {
                scanf("%d",&x);
                add(i,x);
            }
        }
        scanf("%d",&m);
        cnt=0;
        for(int x,y,i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(x==y)
                ans[i]=x;
            adds(x,y),adds(y,x);
        }
        for(int i=1;i<=n;i++)
            f[i]=i;
        tarjan(1,0);
        printf("Case %d:\n",++cntc);
        for(int i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ivanovcraft/p/9754452.html