zoukankan      html  css  js  c++  java
  • [算法笔记]带权并查集

    带权并查集是普通并查集的进阶版本,功能更加强大。

    普通并查集只能判断两个元素是否在一个集合中,带权并查集可以维护集合元素之间的关系,这个关系由每个元素的权值维护。

    对权值的维护,我们需要在find(),unite()操作中分别进行修改。

    例:399. 除法求值

    class UnionFind {
    public:
        unordered_map<string, string> p;
        unordered_map<string, double> d;
    
        UnionFind(vector<vector<string>>& equations, vector<double>& values) {
            for (int i = 0; i < values.size(); i++) {
                string a = equations[i][0], b = equations[i][1];
                // 可能某个结点多次出现,防止对其初始化,导致覆盖
                if (!p.count(a)) {
                    p[a] = a;
                    d[a] = 1;
                }
                if (!p.count(b)) {
                    p[b] = b;
                    d[b] = 1 ;
                }
                unite(a, b, values[i]);
            }
        }
        string find(string x) {
            if (x != p[x]) {
                auto t = find(p[x]);
                d[x] *= d[p[x]];
                p[x] = t;
            }
            return p[x];
        }
        void unite(string a, string b, double v) {
            string ra = find(a), rb = find(b);
            if (ra != rb) {
                p[ra] = rb;
                d[ra] = v * d[b] / d[a];
            }
        }
    };
    

    初始化:a, b是两个需要合并的结点,v是它们的值,a,b满足一个关系式,即(a / b = v)

    find():

    ​ 我们同样进行路径压缩,路径压缩实际上就是将结点x,跳过x的父结点等等,直接与x的根结点相连。普通并查集我们可以直接相连,但是带权并查集我们需要维护结点权值。

    ​ 如图,(a->c)的权值就等于(a->b * b -> c),类似于带权有向图,我们要保证(a->c)的距离不变,换句话说,维护了(a->b->c)的路径权值和。

    unite:

    ​ 普通并查集中我们只要:

    x = find(x), y = find(y);
    p[x] = y;
    

    ​ 带权并查集中:考虑$ x / y = v$。

    ​ 结点x,y可能有多种情况,可能(x == y, find(x) == x || find(y) == y)

    ​ 我们直接考虑最复杂的情况,即(find(x) !!= x && find(y) != y),这种情况是最复杂的,其他情况都是该情况的特殊情况!

    ​ 观察图可得,蓝色线代表权值v(蓝色线不会相连,这里只是做出显示),为了维护 四边形法则(也就是X->Y无论从那条路径走,路径权值和应该相等),我们可以求得 (V_x=V*V_2/V_1)

  • 相关阅读:
    js 正则表达式 test match exec三个方法的异同
    网页使用MD5加密
    解决Google地图和字体api无法加载的问题(转)
    Javascript 的addEventListener()及attachEvent()区别分析
    get与post的区别
    清除浮动的几种方法
    zoom属性(IE私有属性)
    class,id和name的区别
    深夜偷精之反射函数
    jQuery和js区别
  • 原文地址:https://www.cnblogs.com/enmac/p/13962764.html
Copyright © 2011-2022 走看看