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

      学习带权并查集之前我们需要先对并查集和路径压缩压缩了解,有需求的可以参考这篇博客

    刚昨天总结了并查集的相关操作,今天做题的时候居然发现自己一直都是存在一些想不到的地方,总是会存在一些漏洞,最骚的是今天做到了食物链这道题......才知道了带权并查集和种类并查集......好了接下

    来就要进入带权并查集了。

      上面的博客中有写到路径压缩的相关操作,我们知道路径压缩的结果就是同一集合中的所有元素统一指向树根,这样可以加快访问速度。和路径压缩一样,带权并查集仅仅是在每个集合元素都指向树根

    的前提下赋予这些结点相对于树根的权值。

      那么我们就需要用一个数组一个元素相对于他所属集合树根的权值,我们用value存储。

      我们已经知道了基本并查集的一般实现,但是如果加入了value要如何实现呢。

      

      我们思考:

        在find函数中,我们对于每个元素进行一次赋值,使得最终所有元素的父亲结点都指向树根结点,那么如果带有权值的话,我们知道每次都会改变一个结点的父亲,知道找到他所属集合的树根,所以

      我们每次也需要更新对应的value值。

        那么合并函数呢,我们知道每次合并我们会将x所属集合的树根px的父亲设置为y所属集合的树根py,这样就可以将两个集合合并,那么我们知道在这过程中我们改变了px的父亲,也就需要改变px对

    应他父亲的权值,我们根据下图就可以知道,对于value[px],因为x最终父亲为py,所以显然两条路的权值应该相等,我们就可以得出如下代码。

        并不是所有类型的更新都是下面这种情况,具体情况具体分析,但是思路宝贵。

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 const int maxn = 10000 + 5;
     6 int head[maxn], value[maxn], rank[maxn];
     7 
     8 int find(int u) {
     9     if(u != head[u]) {
    10         int t = head[u];
    11         head[u] = find(head[u]);
    12         value[u] += value[t];
    13     }
    14     return head[u];
    15 }
    16 
    17 void Union_Set(int x, int y, int s) {
    18     int fx = find(x), fy = find(y);
    19     if(fx == fy) return;
    20     if(rank[fx] > rank[fy]) {
    21         head[fy] = fx;
    22         value[fy] = -value[y] + value[x] + s;
    23     } else {
    24         head[fx] = fy;
    25         value[fx] = -value[x] + value[y] + s;
    26         if(rank[fx] == rank[fy]) rank[fy] ++;
    27     }
    28 }
    29 
    30 int is_same(int x, int y) {
    31     return find(x) == find(y);
    32 }
    33 
    34 int main () {
    35 
    36     return 0;
    37 }  

      后续会更新相关题目:针对题目再做详细描述。

  • 相关阅读:
    PAT (Advanced Level) Practice 1100 Mars Numbers (20分)
    PAT (Advanced Level) Practice 1107 Social Clusters (30分) (并查集)
    PAT (Advanced Level) Practice 1105 Spiral Matrix (25分)
    PAT (Advanced Level) Practice 1104 Sum of Number Segments (20分)
    PAT (Advanced Level) Practice 1111 Online Map (30分) (两次迪杰斯特拉混合)
    PAT (Advanced Level) Practice 1110 Complete Binary Tree (25分) (完全二叉树的判断+分享致命婴幼儿错误)
    PAT (Advanced Level) Practice 1109 Group Photo (25分)
    PAT (Advanced Level) Practice 1108 Finding Average (20分)
    P6225 [eJOI2019]异或橙子 树状数组 异或 位运算
    P4124 [CQOI2016]手机号码 数位DP
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10723041.html
Copyright © 2011-2022 走看看