• 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
  • 相关阅读:
    四十五、android camera
    MyEclipse优化技巧
    设置MyEclipse编码、补全快捷键、字体大小
    妈妈走开一会儿
    四十一、Android Notification通知详解
    四十三、设置Activity永不过期,即不执行onDestroy()
    七、oracle 表查询二
    四十七、实现调用Android手机的拍照功能
    四十四、Android之android:layout_weight详解
    一、oracle 高水位线详解
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11315982.html
Copyright © 2020-2023  润新知