zoukankan      html  css  js  c++  java
  • HDU6031 Innumerable Ancestors

    O(n^2)暴力枚举点然后算LCA显然是不可行的。

    看到这个数据范围,考虑二分。我们二分枚举LCA的深度mid,然后把set A中每个点深度为mid的祖宗找出来,看set B中每个点深度为mid的祖宗有没有与set A刚才找到的祖宗重合,如果有重合,l=mid+1,否则r=mid-1。

    记得多组数据。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define int long long
    const int N=1e5,LOGN=20;
    int fa[N+10][20],head[N+10],ver[N*2+10],nxt[N*2+10],tot=0,dep[N+10];
    void add(int x,int y)
    {
        ver[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    int getfa(int x,int k)
    {
        int ans=x,pos=0;
        while((1<<pos)<=k)
        {
            if((1<<pos)&k) ans=fa[ans][pos];
            pos++;
        }
        return ans;
    }
    bool vis[N+10];
    int que[N+10],h=1,t=0,zzt;
    void bfs()
    {
        que[++t]=1;
        dep[1]=1;
        while(h<=t)
        {
            int x=que[h]; h++;
            // printf("x:%lld
    ",x);
            vis[x]=1;
            for(int i=head[x];i;i=nxt[i])
            {
                int y=ver[i];
                if(vis[y]) continue;
                fa[y][0]=x;
                dep[y]=dep[x]+1;
                // maxdep=max(maxdep,dep[y]);
                for(int j=1;j<=zzt;j++) fa[y][j]=fa[fa[y][j-1]][j-1];
                que[++t]=y;
            }
        }
    }
    vector<int> s1,s2;
    int k1,k2;
    int book[N+10];
    int maxdep; 
    int bs(int pos) //binary search
    {
        int l=1,r=maxdep,ans=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            // printf("mid:%lld
    ",mid);
    
            bool flag=0;
    
            for(int i=0;i<k1;i++) 
                if(dep[s1[i]]>=mid)
                    book[getfa(s1[i],dep[s1[i]]-mid)]=pos;
            for(int i=0;i<k2;i++)
                if(dep[s2[i]]>=mid)
                    if(book[getfa(s2[i],dep[s2[i]]-mid)]==pos)
                    {
                        flag=1;
                        break;
                    }
            if(flag)
            {
                l=mid+1;
                ans=mid;
            }
            else r=mid-1;
        }
        return ans;
    }
    signed main()
    {
        int n,m;
        while(~scanf("%lld %lld",&n,&m))
        {
            memset(book,0,sizeof(book));
            h=1;t=0;
            memset(vis,0,sizeof(vis));memset(head,0,sizeof(head));tot=0;
            
            zzt=log2(n)+1;
            for(int i=1;i<n;i++)
            {
                int u,v;
                scanf("%lld %lld",&u,&v);
                add(u,v);
                add(v,u);
            }
            bfs();
            for(int i=1;i<=m;i++)
            {
                maxdep=0;
                s1.clear();s2.clear();
                scanf("%lld",&k1);
                for(int j=1;j<=k1;j++)
                {
                    int x;
                    scanf("%lld",&x);
                    s1.push_back(x);
                    maxdep=max(maxdep,dep[x]);
                }
                scanf("%lld",&k2);
                for(int j=1;j<=k2;j++)
                {
                    int x;
                    scanf("%lld",&x);
                    s2.push_back(x);
                    maxdep=max(maxdep,dep[x]);
                }
                printf("%lld
    ",bs(i));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    QT自定义控件插件化简要概述
    wildfly9 配置SSL单向认证/https
    wildfly-9.0.2 web项目部署详细步骤
    SQL Server 2008 数据库日志文件丢失处理方法
    win7 64位系统 pl/sql 无法解析指定的连接标识符解决办法
    mybatis 应用参考
    去除浏览器下jquey easyui datagrid、combotree 缓存问题
    java 页面url传值中文乱码的解决方法
    jasperreports-5.6 + jaspersoftstudio-5.6 生成pdf 文件中文无法正常显示问题
    HTML5实现在线抓拍
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/13892360.html
Copyright © 2011-2022 走看看