zoukankan      html  css  js  c++  java
  • LCA模板

    代码

    //maxn是点的最大个数,首先init,然后用G加边,接下来调用dfs(根,1),ST(节点个数),
    //GetLca(u,v)用于查询两点的lca
    typedef pair<int,int> par;
    struct LCA
    {
        int id,ver[maxn*2],deep[maxn*2];//id先序访问编号,ver保存id对应节点编号,deep深度
        int disc[maxn],fa[maxn]; //disc点被访问时的id,fa父节点
        bool vis[maxn];    //是否被访问过
        vector<int> G[maxn];  //邻接表
        void init(int n=maxn-1) //初始化
        {
            id=0;
            for(int i=0;i<=n;i++)
            {
                vis[i]=false;
                G[i].clear();
                fa[i]=-1;
            }
        }
        void dfs(int u,int h) //深搜一遍把对应信息保存下来
        {
            vis[u]=true;
            ver[++id]=u; deep[id]=h; disc[u]=id;
            int Size=G[u].size();
            for(int i=0;i<Size;i++)
            {
                int v=G[u][i];
                if(vis[v]) continue;
                fa[v]=u;
                dfs(v,h+1);
                ver[++id]=u; deep[id]=h;
            }
            return;
        }
        int Lg[2*maxn];
        par dp[2*maxn][18];
        int f(int x){ return 1<<x; }
        void ST(int n) //RMQ处理部分
        {
            n*=2;
            Lg[0]=-1;
            for(int i=1;i<=n;i++) Lg[i]=Lg[i-1]+((i&(i-1))?0:1);
            for(int i=1;i<=n;i++) dp[i][0]=make_pair(deep[i],ver[i]); //深度和点编号
            for(int j=1;f(j)<=n;j++)
               for(int i=1;i+f(j)-1<=n;i++)
                dp[i][j]=min(dp[i][j-1],dp[i+f(j-1)][j-1]);//lca一定是深度最小的位置
        }
        int GetLca(int u,int v)
        {
            int x=disc[u],y=disc[v];
            if(x>y) swap(x,y);
            int k=Lg[y-x+1];
            par t=min(dp[x][k],dp[y-f(k)+1][k]);
            return t.second;
        }
    }lca;
    View Code
  • 相关阅读:
    JAVA多线程与并发学习总结
    Java虚拟机类加载机制
    2013网易校园招聘笔试题
    人人网面试题
    2010人人网校园招聘笔试题
    2011人人网校园招聘笔试题
    2012人人网校园招聘笔试题
    2013人人网校园招聘笔试题
    海量数据查找唯一数据问题
    Hulu面试题
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5754541.html
Copyright © 2011-2022 走看看