[Disjoint-set] disjoint-set template

A. Disjoint-set can be used to do

Seeking a number of connected components of FIG.

 

II. Disjoint-set basic operations

Disjoint-set is used to query whether an element in a set of + merge two disjoint sets .

He simply two yuan operation; derivatives based on the operation of these two operations have

  1. Compare two elements are in a centralized and check - check and compare two elements are the same set of representatives
  2. And add a check to the centralized element - the element as a separate disjoint-set, and then to make the target set and set operations.

 

Three disjoint-set optimization - path compression algorithm

When we learn to know BST, complexity and its highly relevant time a binary tree looking for. If a linear binary tree, then the search time complexity elements is O (n). In and check focus, too, we have to find ways to reduce the height of the tree.

One thing to note is that in fact disjoint-set corresponding undirected graph is actually more than one tree, but it is good for our program.

Route optimization algorithm is used to reduce the height of our tree, it is mainly from the operation of our two disjoint-set departure:

· Query element

When we query elements the way reconstruction of the branch about the inquiry, all the nodes on the path are directly connected to the root node. FIG below:

· The combined collections

We can not be like under the TBT mount, like the tree to the root of the left subtree right-most node (in fact, this is exactly the opposite approach)

We should take advantage of the nature of its multi-tree to a disjoint-set mounted directly to the other and check on the root set.

We'd better put a small tree height mount to the height of the big tree, so that we would not have the height change.

Of course, if the height of two trees of equal height make it a +1.

(FIG below two FIG Seeing)

 

IV. Templates

In fact, this is not a good template to write (refer to variable naming

But I think as long as written several times, after reading the template can understand the thought of them, that is enough .

// 像union set这种数据结构真的不适合使用成员方法来实现
// 还是像链表一样老老实实地用非成员方法来做好了
// 发现还是使用数组比较方便
constexpr int kNum = 100000;
int parent_[kNum];    // 记录每一个节点的父亲节点编号
int rank_[kNum];      // 用bits/stdc++.h还不能使用rank,不然会重名发生ambigous错误

void Initialize() {
// 初始化
  for (int i = 0; i < kNum; ++i) {
    parent_[i] = i;
    rank_[i] = i;
  }
}

int Find(int x) {
// 找到相应并查集的根节点
  // 根节点的特征
  if (x == parent_[x]) {
    return x;
  }
  return parent_[x] = Find(parent_[x]);   // 继续查找+路径压缩
}

void Union(int x, int y) {
  int parent_x = Find(x);
  int parent_y = Find(y);
  // 如果在同一个并查集内
  if (parent_x == parent_y) {
    return;
  }
  // 如果不在一个并查集内, 根据rank来合并并查集
  // 注意对rank的更新
  if (rank_[parent_x] > rank_[parent_y]) {
    parent_[parent_y] = parent_x;     // y挂到x上
  } else {
    if (rank_[parent_x] == rank_[parent_y]) {
      ++rank_[parent_y];    // 由于接下来要挂到y上
    }
    parent_[parent_x] = parent_y;     // x挂到y上
  }

 

发布了137 篇原创文章 · 获赞 19 · 访问量 1万+

Guess you like

Origin blog.csdn.net/qq_43338695/article/details/102869271