您的位置:首页 > 其它

POJ1470 LCA(tarjan离线求最近公共祖先)

2017-10-10 20:25 519 查看
#include<cstdio>  

#include<cstring>  

const int N = 910;  

  

struct Edge{  

    int e,next;  

}edge[2*N];  

  

int n,m,e_num,head
,vis
,cnt
;  

int x[N*N],y[N*N],f[N*N];  

  

void AddEdge(int a,int b){  

    edge[e_num].e=b; edge[e_num].next=head[a]; head[a]=e_num++;  

    edge[e_num].e=a; edge[e_num].next=head[b]; head[b]=e_num++;  

}  

  

int findx(int x){  

    if(f[x]!=x)return f[x]=findx(f[x]);  

    return f[x];  

}  

  

void tarjan(int k){  

    int i;  

    vis[k]=1;  

    f[k]=k;  

    for(i=1;i<=m;i++){//遍历处理刚才保存的 m 个询问  

        if(x[i]==k && vis[y[i]])cnt[findx(y[i])]++;  

        if(y[i]==k && vis[x[i]])cnt[findx(x[i])]++;  

    }  

    for(i=head[k];i!=-1;i=edge[i].next){  

        if(!vis[edge[i].e]){  

            tarjan(edge[i].e);  

            f[edge[i].e]=k;  

        }  

    }  

}  

  

int main()  

{  

    int i,t,id,a,flag
;  

    char ch1[2],ch2[2],ch3[2];  

    while(~scanf("%d",&n))  

    {  

        e_num=0;  

        for(i=1;i<=n;i++){  

            flag[i]=vis[i]=cnt[i]=0;  

            head[i]=-1;  

        }  

        for(i=1;i<=n;i++){  

            scanf("%d%1s%1s%d%1s",&id,ch1,ch2,&t,ch3);  

            while(t--){  

                scanf("%d",&a);  

                flag[a]=1;  

                AddEdge(id,a);  

            }  

        }  

        scanf("%d",&m);  

        for(i=1;i<=m;i++)  

            scanf("%1s%d%d%1s",ch1,&x[i],&y[i],ch2);  

  

        for(i=1;i<=n;i++)//注意,这里,根节点不一定是 1  

            if(flag[i]==0)break;  

  

        tarjan(i);  

  

        for(i=1;i<=n;i++)  

            if(cnt[i])printf("%d:%d\n",i,cnt[i]);  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: