zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    应用程序连接hbase报错:java.net.SocketTimeoutException: callTimeout=60000
    《30岁前的每一天》读书笔记(一)
    你在为谁工作——IT帮深圳分站2019年3月线下活动回顾
    定义工作,解读自我——IT帮2019年2月线下活动回顾
    2018年终总结
    svn + nginx unit + python3自动化发布web服务方法
    关于nginx unit服务非正常关闭后,无法重新启动问题的处理
    90%以上的人都存在拖延症状,原来你没有做对这一件事
    我们没得拼爹,只能拼命,但拿什么来拼命?
    我们在努力创建自己的幸福生活,可为什么却常常感受不到幸福?
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11315982.html
Copyright © 2011-2022 走看看