• LCA (Tarjan&倍增)


    LCA_Tarjan

    参考博客:https://www.cnblogs.com/JVxie/p/4854719.html

    LCA的Tarjan写法需要结合并查集

    从叶子节点往上并

    int Find (int x) {
        return x == pre[x] ? x:pre[x] = Find(pre[x]);
    }
    void dfs(int x,int w,int fa) {
        d[x] = w;    //点x的深度
        //遍历与点x相连的点(除了已经访问过的和其父节点)
        for (int i = 0; i < v[x].size(); i++) {
            if (!vis[v[x][i]] && v[x][i] != fa) {
                dfs(v[x][i],w+1,x);
                pre[v[x][i]] = x;
                vis[v[x][i]] = 1;
            }
        }
        //访问所有和x有询问关系的e
        //如果e被访问过;
       //x,e的最近公共祖先为find(e);
    }

    LCA_倍增

      参考博客:https://www.cnblogs.com/zhouzhendong/p/7256007.html

      先写暴力写法:当x,y深度不同时先把深的调到和浅的同一深度再一起往前面跳找其最近公共祖先。

    void dfs(int f,int u){
        fa[u]=f;
        d[u]=d[f]+1;
        for (int i=0;i<v[u].size();i++)
            if (v[u][i]!=f) dfs(u,v[u][i]);
    }
    int LCA(int a,int b){
        if (d[a]>d[b])
            swap(a,b);
        while (d[b]>d[a]) b=fa[b];
        while (a!=b) a=fa[a],b=fa[b];
        return a;
    }

      显然,一个一个的跳太慢了,我们可以考虑通过二进制进行优化,也就是倍增。

    void dfs(int f,int u) {
        fa[u][0] = f;
        dep[u] = dep[f] + 1;
        for (int i = 1; i <= 15; i++) {
            fa[u][i] = fa[fa[u][i-1]][i-1];
            //其他操作
        }
        for (int i = 0; i < v[u].size(); i++) {
            if (f == v[u][i]) continue;
            dfs(u,v[u][i]);
        }
    }
    void lca(int x,int y) {
        memset(ans,0,sizeof(ans));
        if (dep[x] < dep[y]) swap(x,y);
        for (int i = 15; i >= 0; i--) 
            if (dep[fa[x][i]] >= dep[y]) {
                //其他操作
                x = fa[x][i];
            }
        if (x == y) {
            return;
        }
        for (int i = 15; i >= 0; i--) 
            if (fa[x][i] != fa[y][i]) {
                //其他操作
                x = fa[x][i],y = fa[y][i];
            }
    }

    例题:洛谷P3292 [SCOI2016]幸运数字  | 题解

  • 相关阅读:
    Redis学习笔记——环境搭建
    SQL 记录
    路径“D:svn.....”的访问被拒绝问题处理
    去除浏览器自动给input赋值的问题
    获取用户IP
    JS对身份证号码进行验证方法
    JS 实现倒计时
    SQL 游标
    .net上传图片实例
    生成唯一码
  • 原文地址:https://www.cnblogs.com/l999q/p/11291627.html
Copyright © 2020-2023  润新知