Examples of tree applications - union search and tree arrays

And lookup

Union search uses the forest to describe some disjoint sets, and supports the merge operation and query operation of the sets.

Suppose there are n elements, divided into m disjoint sets, a set constitutes a tree, and the elements in the same tree (set) are of equal status. For example, the forest in the figure below represents a union search set containing 18 elements, which is divided into three sets: sets 1, 9, and 13.

Path compression: 

        While merging trees, consider reducing the height of the tree, which is generally used in query operations.

Implementation method:
        
When querying node x, not only the root node of the tree where it is located is obtained, but also the parent nodes of all nodes on the path from x to the root node are adjusted to the root node.

Perform path compression on Figure 3-22(a) to get the following figure

 

#include<iostream>
using namespace std;
typedef int datatype;
constexpr auto N = 100;
//由并查集的两种操作可知,并查集的操作中主要涉及结点的父节点和树的根结点,
//因此可以采用树的双亲表示法表示并查集。
//由下面并查集的类型定义可知,初始并查集每个集合里就一个元素,mq即表示一个并查集。
struct mqNode {
	int pa;
	datatype data;
	mqNode() :pa(-1) {};
}mq[N];

//并查集的查询操作
int query(int x) {
	if (mq[x].pa == -1)return x; //x没有父节点,则x为根结点
	mq[x].pa = query(mq[x].pa); //向上查询x的父节点,并进行路径压缩,让x到根结点的路径都独立出来,成为第二层节点,链接根结点
	return mq[x].pa;
}

//并查集的合并操作:1.获取两个元素所在树的根结点 2.检查两个元素是否属于同一集合
void merge(int x, int y) {
	x = query(x), y = query(y);
	if (x != y)
		mq[x].pa = y;
}

int main() {

}

And lookup application example

Union search set is a very useful data structure, which is used in Kruskal algorithm and when judging whether an undirected graph is a connected graph. The following uses an example to illustrate the use of union search.
[Example] There is a choir in the school. The members of the choir are selected from various majors in the school, and there are n students in total. Now ask whether any two students are from the same class. After several inquiries, it is assumed that there are m pairs of students who get an affirmative answer. According to m pairs of student information, determine how many different classes the members of the choir come from at most.
        For example, there are 10 members in the choir, numbered from 1 to 10, let m=7, and the 7 pairs of students are (1,2), (2,6), (3,4), (8,5 ), (5,4) , (9 10), (6, 1). It can be seen that 1, 2, 6 are from the same class, 3, 4, 5, 8 are from the same class, 9, 10 are from the same class, 7 has no information, so these 10 students come from at most 4 classes.
        Obviously, this problem can be solved by union search, which is to merge the sets of two students from the same class, and finally
just count the number of sets.

void merge(int x, int y) {
	x = query(x), y = query(y);
	if (x != y)
		mq[x].pa = y;
}

int num_class() {
	int n, m, x, y, ret = 0;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> x >> y;  //输入在同一班的两位学生编号
		merge(x, y); //合并操作
	}
	for (int i = 0; i < n; i++) //统计集合数量
		ret += mq[i].pa == -1;
	return ret;
}

tree array

 

 

Guess you like

Origin blog.csdn.net/qq_62687015/article/details/128744291