zoukankan      html  css  js  c++  java
  • 并查集

    并查集有两个优化。

    首先是初始化:

    int fa[maxn], r[maxn];
    
    void init(int n) {
        for (int i=1; i<=n; ++i) {
            fa[i] = i;
            r[i] = 1;
        }
    }
    

    优化:

    一、按秩合并

    描述:就是在对两个不同子集连接时,按照rank来连,也就是rank低的连在rank高的下面。rank高的做父亲节点。

    作用,这样类似维护了一棵树,树是rank高的在上。

    void unin(int u, int v) { // 非按秩合并
        int fau = find_fa(u);
        int fav = find_fa(v);
        if (fau != fav)
            fa[fav] = fau;
    }
    

      

    void unin(int u, int v) { // 按秩合并
        int fau = find_fa(u);
        int fav = find_fa(v);
        if (fau == fav) return;
    
        if (r[u] < r[v]) fa[fau] = fav;
        else {
            if (r[u] == r[v])
                r[u]++;
            fa[fav] = fau;
        }
    }
    

      

    二、路径压缩

    描述:假如fa数组已经嵌套了N层,那么传统的做法去找祖先要做N次,当N很大时,这种做法很没效率。

    这是朴素查找的代码,适合数据量不大的情况:

    int findx(int x)
    {
        int r=x;
       while(parent[r] !=r)
            r=parent[r];
       return r;
    }
    

     递归式路径压缩易RE:

    int find_fa(int v) { // 递归式路径压缩
        if (fa[v] != v) fa[v] = find_fa(fa[v]);
        return fa[v];
    }
    

     非递归式路径压缩:

    int find_fa(int v) { // 非递归式路径压缩
        int k, j, r;
        r = v;
        while(r != fa[r])
            r = fa[r]; //找到根节点 记录在r上。
        k = v;
        while(k != r) {
            j = fa[k];
            fa[k] = r;
            k = j;
        }
        return r;
    }
    

      

  • 相关阅读:
    mysql
    Spring MVC
    springSecurity
    导出Excel报表
    Redis集群搭建
    Oracle 分析数据库表行长度的统计信息 使用聚簇的步骤
    Dbms.job 学习
    oracel 学习系列
    Oracle 工具类 Sql 分析索引的 碎片率
    oracl
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5296488.html
Copyright © 2011-2022 走看看