• 最近在写一些树上的东西,先发一波LCA的吧!


    不会树剖的我只有去学tarjan和倍增了,个人觉得倍增比tarjan好打一点。。。

    tarjan学习的地方

    http://www.cnblogs.com/JVxie/p/4854719.html

    个人写的模板(洛谷的模板题,左右移符号打翻了,挑了好久QAQ)

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    #define maxn 500500 << 1
    using namespace std;
    
    ll head[maxn],head_quest[maxn],tot,n,m,u,v,val,root,f[maxn],ceng[maxn],zou[maxn];
    
    struct st{
        ll v,next;
    }s[maxn];
    
    struct que{
        ll u,v,lca,next;
        que *es;
    }quest[maxn];
    
    void add(ll u,ll v)
    {
        tot++;
        s[tot].v = v;
        s[tot].next = head[u];
        head[u] = tot;
    }
    
    void addquest(ll u,ll v)
    {
        tot++;
        if(tot & 1) quest[tot].es = &quest[tot + 1];
        else quest[tot].es = &quest[tot - 1];
        quest[tot].u = u;
        quest[tot].v = v;
        quest[tot].next = head_quest[u];
        head_quest[u] = tot;
    }
    
    ll find(ll x)
    {
        if(f[x] == x) return x;
        f[x] = find(f[x]);
        return f[x];
    }
    
    void dfs(ll fa,ll pos)
    {
        ceng[pos] = ceng[fa] + 1;
        for(ll i=head[pos];i;i=s[i].next)
            if(s[i].v != fa)
                dfs(pos,s[i].v);
    }
    
    void tarjan(ll fa,ll pos)
    {
        for(ll i=head[pos];i;i=s[i].next)
        {
            if(s[i].v == fa) continue;
            tarjan(pos,s[i].v);
        }
        for(ll i=head_quest[pos];i;i=quest[i].next)
        {
            if(zou[quest[i].v])
            {
                quest[i].lca = find(quest[i].v);
                quest[i].es -> lca = quest[i].lca;
            }
        }
        zou[pos] = 1;
        f[pos] = fa;
    }
    
    int main(){
        scanf("%lld%lld%lld",&n,&m,&root);
        for(ll i=1;i<n;i++)
        {
            scanf("%lld%lld",&u,&v);
            add(u,v);
            add(v,u);
        }
        
        dfs(0,root);
        
        tot = 0;
        for(ll i=1;i<=m;i++)
        {
            scanf("%lld%lld",&u,&v);
            addquest(u,v);
            addquest(v,u);
        }
        
        for(ll i=1;i<=n;i++) f[i] = i;
        tarjan(0,root);
        for(ll i=1;i<=2*m;i+=2)
            printf("%lld
    ",quest[i].lca);
    }

    接下来是倍增

    学习:

    http://www.cnblogs.com/FuTaimeng/p/5655616.html

     自己写的模板(在洛谷交的时候忘了边要开两倍QAQ)

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define maxn 1000500
    #define ll long long 
    using namespace std;
    struct st{
        ll u,v,next;
    }s[maxn];
    ll n,m,u,v,root,tot,head[maxn],ceng[maxn],fa[maxn][20];
    
    inline void add(ll u,ll v)
    {
        tot++;
        s[tot].u = u;
        s[tot].v = v;
        s[tot].next = head[u];
        head[u] = tot;
    }
    
    inline void dfs(ll f,ll now)
    {
        fa[now][0] = f;
        ceng[now] = ceng[f] + 1;
        for(ll i = head[now];i;i = s[i].next)
        {
            if(s[i].v != f)
                dfs(now,s[i].v);
        }
    }
    
    inline void init()
    {
        for(ll j=1;(1<<j)<=n;j++)
            for(ll i=1;i<=n;i++)
                fa[i][j] = fa[fa[i][j-1]][j-1];  
    }
     
    inline ll lca(ll a,ll b)
    {
        if(ceng[a] > ceng[b]) swap(a,b);
        ll cha = ceng[b] - ceng[a];
        for(ll i = 0;(1 << i) <= cha;i++)
        {
            if((1 << i) & cha) b = fa[b][i];
        }
        if(a != b)
        {
            for(ll i=(ll)log2(n);i>=0;i--)
            {
                if(fa[a][i] != fa[b][i])
                {
                    a=fa[a][i];
                    b=fa[b][i];
                }
            }
            a = fa[a][0];
        }
        return a;
    }
    int main(){
        scanf("%lld%lld%lld",&n,&m,&root);
        for(ll i=1;i<n;i++)
        {
            scanf("%lld%lld",&u,&v);
            add(u,v);
            add(v,u);
        }
        
        dfs(0,root);
        init();
        for(ll i=1;i<=m;i++)
        {
            scanf("%lld%lld",&u,&v);
            printf("%lld
    ",lca(u,v));
        }
    } 
  • 相关阅读:
    Unity文件操作路径
    自定义协议封装包头、包体
    完全卸载删除gitlab
    shell脚本报错:syntax error: unexpected end of file
    Shell脚本创建的文件夹末尾有两个问号怎么回事?
    您与此网站之间建立的连接并非完全安全
    linux 查看磁盘文件大小
    mysql连接问题
    Linux查看当前开放的端口
    本地Linux备份服务器[Client]定期备份云服务器[Server]上的文件(下)
  • 原文地址:https://www.cnblogs.com/kczno1fans/p/7731708.html
Copyright © 2020-2023  润新知