• 1143 Lowest Common Ancestor (30 分)


    好家伙,(unordered\_map)一直有一两个点超时,换成数组就过了,看来(STL)实现的哈希表还是没数组快啊。

    向上标记法。

    const int N=10010;
    int fa[N];
    unordered_map<int,int> pos;
    int pre[N],in[N];
    bool vis[N];
    int n,m;
    
    int build(int prel,int prer,int inl,int inr)
    {
        if(prel > prer) return -1;
    
        int root=pre[prel];
        int k=pos[root];
        int leftLen=k-inl;
        int lchild=build(prel+1,prel+leftLen,inl,k-1);
        int rchild=build(prel+leftLen+1,prer,k+1,inr);
    
        if(~lchild) fa[lchild]=k;
        if(~rchild) fa[rchild]=k;
        return k;
    }
    
    int LCA(int u,int v)
    {
        memset(vis,0,sizeof vis);
        while(u)
        {
            vis[u]=true;
            u=fa[u];
        }
        
        while(!vis[v]) v=fa[v];
        return v;
    }
    
    int main()
    {
        cin>>m>>n;
    
        for(int i=1;i<=n;i++)
        {
            cin>>pre[i];
            in[i]=pre[i];
        }
    
        sort(in+1,in+n+1);
        for(int i=1;i<=n;i++)
            pos[in[i]]=i;
    
        build(1,n,1,n);
    
        while(m--)
        {
            int u,v;
            cin>>u>>v;
            if(pos.count(u) == 0 && pos.count(v) == 0)
                printf("ERROR: %d and %d are not found.",u,v);
            else if(pos.count(u) == 0)
                printf("ERROR: %d is not found.",u);
            else if(pos.count(v) == 0)
                printf("ERROR: %d is not found.",v);
            else
            {
                u=pos[u],v=pos[v];
                int lca=LCA(u,v);
                if(lca != u && lca != v)
                    printf("LCA of %d and %d is %d.",in[u],in[v],in[lca]);
                else if(lca == u)
                    printf("%d is an ancestor of %d.",in[u],in[v]);
                else
                    printf("%d is an ancestor of %d.",in[v],in[u]);
            }
            puts("");
        }
        //system("pause");
        return 0;
    }
    

    同步前进法。

    const int N=10010;
    int fa[N];
    unordered_map<int,int> pos;
    int pre[N],in[N];
    int dep[N];
    int n,m;
    
    int build(int prel,int prer,int inl,int inr,int d)
    {
        if(prel > prer) return -1;
    
        int root=pre[prel];
        int k=pos[root];
        dep[k]=d;
        int leftLen=k-inl;
        int lchild=build(prel+1,prel+leftLen,inl,k-1,d+1);
        int rchild=build(prel+leftLen+1,prer,k+1,inr,d+1);
    
        if(~lchild) fa[lchild]=k;
        if(~rchild) fa[rchild]=k;
        return k;
    }
    
    int LCA(int u,int v)
    {
        if(dep[u] < dep[v]) swap(u,v);
        
        while(dep[u] != dep[v]) u=fa[u];
        if(u == v) return v;
        while(fa[u] != fa[v])
        {
            u=fa[u];
            v=fa[v];
        }
        return fa[u];
    }
    
    int main()
    {
        cin>>m>>n;
    
        for(int i=1;i<=n;i++)
        {
            cin>>pre[i];
            in[i]=pre[i];
        }
    
        sort(in+1,in+n+1);
        for(int i=1;i<=n;i++)
            pos[in[i]]=i;
    
        build(1,n,1,n,1);
    
        while(m--)
        {
            int u,v;
            cin>>u>>v;
            if(pos.count(u) == 0 && pos.count(v) == 0)
                printf("ERROR: %d and %d are not found.",u,v);
            else if(pos.count(u) == 0)
                printf("ERROR: %d is not found.",u);
            else if(pos.count(v) == 0)
                printf("ERROR: %d is not found.",v);
            else
            {
                u=pos[u],v=pos[v];
                int lca=LCA(u,v);
                if(lca != u && lca != v)
                    printf("LCA of %d and %d is %d.",in[u],in[v],in[lca]);
                else if(lca == u)
                    printf("%d is an ancestor of %d.",in[u],in[v]);
                else
                    printf("%d is an ancestor of %d.",in[v],in[u]);
            }
            puts("");
        }
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    P1182 数列分段`Section II`
    算法整理:Floyd_多源最短路
    【FBI WARNING】递归(高级数据结构的基础)
    【FBI WARNING】DP 从看透到看开
    两个例题
    结构体
    环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
    生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
    猜数字游戏的提示(Master-Mind Hints, UVa 340)
    回文词(Palindromes, UVa401)
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14523020.html
Copyright © 2020-2023  润新知