• ZOJ 1141:Closest Common Ancestors(LCA)


    Closest Common Ancestors


    Time Limit: 10 Seconds      Memory Limit: 32768 KB

    Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ancestor of two nodes u and v is the node w that is an ancestor of both u and v and has the greatest depth in the tree. A node can be its own ancestor (for example in Figure 1 the ancestors of node 2 are 2 and 5)

    The data set starts with the tree description, in the form:

    nr_of_vertices
    vertex:(nr_of_successors) successor1 successor2 ... successorn
    ......

    where vertices are represented as integers from 1 to n. The tree description is followed by a list of pairs of vertices, in the form:

    nr_of_pairs
    (u v) (x y) ...

    The input contents several data sets (at least one).

    Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.

    For each common ancestor the program prints the ancestor and the number of pair for which it is an ancestor. The results are printed on the standard output on separate lines, in to the ascending order of the vertices, in the format: ancestor:times

    For example, for the following tree:

    the program input and output is:


    Input

    5
    5:(3) 1 4 2
    1:(0)
    4:(0)
    2:(1) 3
    3:(0)
    6
    (1,5) (1,4) (4,2)
    (2,3)
    (1,3) (4,3)


    Output

    2:1
    5:5

    题意

    给出一颗树, n 次查询最近公共祖先,输出所有查询所涉及到顶点的次数,未涉及则不输出。

    思路

    LCA模板,在输入查询的时候,用scanf(" (%d,%d)",&x,&y);输入,注意"("左边有一个空格

    不知道为什么在POJ过不了,又是TLE又是MLE又是RE的,UVA,ZOJ,CSU都能过

    代码

    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define ll long long
    #define ull unsigned long long
    #define ms(a,b) memset(a,b,sizeof(a))
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=1e6+10;
    const int mod=1e9+7;
    const int maxm=3e3+10;
    const int maxq=1e6+10;
    using namespace std;
    struct Edge
    {
        int to,Next;
    }edge[maxm<<1];
    int head1[maxm];
    int tot1;
    int ans[maxm];
    void add_edge(int u,int v)
    {
        edge[tot1].to=v;
        edge[tot1].Next=head1[u];
        head1[u]=tot1++;
    }
    struct Query
    {
        int to,Next;
        int index;
    }query[maxq];
    int head2[maxm];
    int tot2;
    void add_query(int u,int v,int index)
    {
        query[tot2].to=v;
        query[tot2].Next=head2[u];
        query[tot2].index=index;
        head2[u]=tot2++;
    }
    int f[maxm];
    int find(int x)
    {
        if(f[x]!=x)
            f[x]=find(f[x]);
        return f[x];
    }
    void join(int x,int y)
    {
        int dx=f[x],dy=f[y];
        if(dx!=dy)
            f[dy]=dx;
    }
    bool vis[maxm];
    int fa[maxm];
    int num[maxm];
    void LCA(int u)
    {
        fa[u]=u;
        vis[u]=1;
        for(register int i=head1[u];~i;i=edge[i].Next)
        {
            int v=edge[i].to;
            if(vis[v])
                continue;
            LCA(v);
            join(u,v);
            fa[find(u)]=u;
        }
        for(register int i=head2[u];~i;i=query[i].Next)
        {
            int v=query[i].to;
            if(vis[v])
                ans[query[i].index]=fa[find(v)];
        }
    }
    bool isroot[maxm];
    inline void init(int n)
    {
        tot1=0;tot2=0;
        ms(head1,-1);ms(head2,-1);
        ms(vis,0);ms(isroot,true);
        ms(num,0);
        for(register int i=1;i<=n;i++)
            f[i]=i;
    }
    int main(int argc, char const *argv[])
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/wzy/in.txt", "r", stdin);
            freopen("/home/wzy/out.txt", "w", stdout);
            srand((unsigned int)time(NULL));
        #endif
        int n;
        int cnt,h,p;
        while(scanf("%d",&n)==1)
        {
            init(n);
            for(register int i=1;i<=n;i++)
            {
                scanf("%d:(%d)",&h,&cnt);
                for(int j=0;j<cnt;j++)
                    scanf("%d",&p),add_edge(p,h),add_edge(h,p),isroot[p]=false;
            }
            int root;
            for(register int i=1;i<=n;i++)
                if(isroot[i])
                    root=i;
            int q;
            scanf("%d",&q);
            int x,y;
            for(register int i=0;i<q;i++)
            {
                scanf(" (%d,%d)",&x,&y);
                add_query(x,y,i);add_query(y,x,i);
            }
            LCA(root);
            for(register int i=0;i<q;i++)
                num[ans[i]]++;
            for(register int i=1;i<=n;i++)
                if(num[i])
                    printf("%d:%d
    ",i,num[i]);
        }
        #ifndef ONLINE_JUDGE
            cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
        #endif
        return 0;
    }
    View Code
  • 相关阅读:
    蝴蝶自在——《萍踪侠影》
    学习OpenCV——关于三通道的CvMat的求和问题
    MFC中的OnTimer和SetTimer
    慎重选择博士后(或博士生)导师
    MFC界面的完善
    MFC CSplitterWnd的用法
    断言(ASSERT)的用法
    OpenCV中lib的添加
    【转】数据结构之位图
    【转】关于windows server 2003不能共享问题
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11315982.html
Copyright © 2020-2023  润新知