poj 1470 LCA 离线算法

/*
LCA
求每个点被作为最近公共祖先的次数
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=4012;//node
const int maxm=252;//query
int flag[maxn],n,m,N,M,t,query,cnt[maxn],head[maxn],Head[maxn],vis[maxn],fa[maxn],NE;
struct node
{
    int u,v,d,next;
}Edge[maxn*maxm],edge[maxn*maxm];
void addEdge(int u,int v)
{
    Edge[NE].u=u,Edge[NE].v=v,Edge[NE].next=head[u];
    head[u]=NE++;
}
void addedge(int u,int v)
{
    edge[NE].u=u,edge[NE].v=v,edge[NE].next=Head[u];
    Head[u]=NE++;
}
int find(int i)
{
    return fa[i]==i?i:find(fa[i]);
}
void Tarjan(int u){
    vis[u] = 1;
    fa[u] = u;
    for (int i = Head[u];i!=-1; i=edge[i].next){
        int v=edge[i].v;
        if(vis[v]){
           cnt[find(v)]++; // 存的是最近公共祖先结点
        }
    }
    for(int i= head[u];i!=-1;i=Edge[i].next){
        int v=Edge[i].v;
        if(!vis[v]){
            Tarjan(v);
            fa[v] = u;
        }
    }
}
int main()
{
    int i,j,u,v,root;
    //freopen("//media/学习/ACM/input.txt","r",stdin);
    while(scanf("%d", &N) != EOF){
        memset(head,-1,sizeof(head));
        memset(Head,-1,sizeof(Head));
        memset(flag, 0, sizeof(flag));
        memset(vis, 0, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        for (NE=0,i = 1; i <= N; i++){ //数据的读入方式很不错啊
            scanf("%d", &u);
            while(getchar() != '(');
            scanf("%d", &n);
            while(getchar() != ')');
            while(n--){
                scanf("%d", &v);
                flag[v] = 1;
                addEdge(u,v);
                addEdge(v,u);
            }
        }
        scanf("%d", &M);
        for (NE=0,i = 1; i <= M; i++){
            while(getchar() != '(');
            scanf("%d%d", &u, &v);
            while(getchar() != ')');
           addedge(u,v);
           addedge(v,u);
        }
        for (i = 1; i <= N; i++){// 第一个结点不一定是根结点
            if(flag[i] == 0) break;
        }
        root = i;
        Tarjan(root);
        for (i = 1; i <= N; i++){
            if(cnt[i]){
                printf("%d:%d\n", i, cnt[i]);
            }
        }
 }

    return 0;
}

你可能感兴趣的:(poj 1470 LCA 离线算法)