POJ 1470 Closet Conmon Ancestors(LCA在线算法)

来源:互联网 发布:武汉软件职业技术学院 编辑:程序博客网 时间:2024/04/28 15:25
////  main.cpp//  Richard////  Created by 邵金杰 on 16/9/12.//  Copyright © 2016年 邵金杰. All rights reserved.//#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int maxn=2000;int ver[maxn*2],dep[maxn*2],first[maxn],vis[maxn],root[maxn],head[maxn],dp[maxn*2][16],times[maxn];int n;struct edge{    int v,next;}edge[maxn*2];int cnt,tot;void add_edge(int u,int v){    edge[cnt].v=v;    edge[cnt].next=head[u];    head[u]=cnt++;}void dfs(int fa,int d){    vis[fa]=1;    ver[++tot]=fa;    first[fa]=tot;    dep[tot]=d;    for(int i=head[fa];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(!vis[v])        {            dfs(v,d+1);            ver[++tot]=fa;            dep[tot]=d;        }    }}void ST(int N){    for(int i=1;i<=N;i++) dp[i][0]=i;    for(int j=1;(1<<j)<=N;j++)    {        for(int i=1;i<=N;i++)        {            if(i+(1<<(j-1))<=N)            {                int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];                dp[i][j]=dep[a]<dep[b]?a:b;            }        }    }}int RMQ(int x,int y){    int k=floor(log(y-x+1)/log(2));    int a=dp[x][k],b=dp[y-(1<<k)+1][k];    return dep[a]<dep[b]?a:b;}int LCA(int u,int v){    int x=first[u],y=first[v];    if(x>y) swap(x,y);    int pos=RMQ(x,y);    return ver[pos];}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        memset(vis,0,sizeof(vis));        memset(root,0,sizeof(root));        memset(head,-1,sizeof(head));        memset(dp,0,sizeof(dp));        memset(times,0,sizeof(times));        cnt=0;tot=0;        int u,v,len;        for(int i=0;i<n;i++)        {            scanf("%d:(%d)",&u,&len);            for(int j=0;j<len;j++){                scanf("%d",&v);                root[v]++;                add_edge(u,v);            }        }        for(int i=1;i<=n;i++){            if(root[i]==0) dfs(i,1);        }        ST(n*2-1);        int q;        scanf("%d",&q);        for(int i=0;i<q;i++)        {            while(getchar()!='(') continue;            scanf("%d%d",&u,&v);            times[LCA(u,v)]++;        }        while(getchar()!=')') continue;        for(int i=1;i<=n;i++)            if(times[i]) printf("%d:%d\n",i,times[i]);    }    return 0;}

0 0
原创粉丝点击