And check the detailed explanation (C/C++)

Union lookup basis

And what is the collection?

Union lookup is an algorithm used to manage the grouping of elements.

What is the function of the concatenated set?

Union lookup can efficiently group elements (merge together), and can quickly query whether two elements belong to the same group.

the structure of the union

merge

A union-find set is a tree-like structure. For example, elements 1 and 2 belong to the same group, and elements 1 and 3 also belong to the same group, then elements 2 and 3 can be merged into the same group through element 1, that is, element 1 is the boss of elements 2 and 3, then element 1 is element 2 and The root of element 3 in the tree structure.

insert image description here

When many groups of elements need to be merged together, it is only necessary to merge the bosses of each group of elements together, that is, let one of the roots point to the other root, so that the two trees are merged into one tree, and the Two groups combined into one group.

insert image description here

Inquire

When we want to query whether two elements belong to the same group, we need to query up the root of the tree along each node. If we finally find that the roots of the two elements are the same, then they belong to the same group. Otherwise, they do not belong to the same group.

insert image description here
As shown in the figure: the roots of elements 2 and 3 are both element 1, so they belong to the same group; the roots of elements 2 and 7 are elements 1 and 5, respectively, and they are different, so they do not belong to the same group.

Code

int f[maxn]; //全名为 father,父节点的意思

//初始化 n个元素 
void Init() {
    
    
	//使每个元素的根节点是其本身
	//即初始时每个元素都是单独的 
	for(int i=1; i<=n; i++) f[i]=i;  
}
//查询树的根
//非递归实现
int Find(int i) {
    
    
	while(f[i] != i) {
    
      //直到元素的父节点是它本身,表示已经查询到了树的根
		i = f[i];
	return i; 			//返回根节点对应的元素 
}

//递归实现
int Find(int i) {
    
    
	if(f[i]==i)      //若元素的根节点为其本身,那么此元素就是树的根 
		return f[i];    //直接返回元素本身即可
	else
		return Find(f[i]); //否则继续查询,知道查询到树的根位置 
}

//简化版
int Find(int i) {
    
    
	return f[i]==i ? f[i] : Find(f[i]);
} 
//合并
void merge(int a, int b) {
    
    
	//先找到两个元素对应的根对应的元素 
	int fa = Find(a); 
	int fb = Find(b);
	if(fa==fb) return;
	else f[fa]=fb;  //否则令元素 a的根指向元素 b的根 
} 

//简化版
void merge(int a, int b) {
    
    
	f[Find(a)] = Find(b);
} 

Optimization 1: Avoid degradation (merge by rank)

Because the structure of the union search set is a tree structure, it is necessary to pay attention to the degradation problem. The way to avoid degeneration is as follows:
First, when we merge, we can record the height of the tree (recorded as rank). Next, when we need to merge two trees, we first judge the heights of the two trees. If they are different, let the root of the tree with the smaller height point to the root with the larger height. As shown below:
insert image description here

Code optimization

Optimize the initialization (Init) function and the merge (merge) function

//初始化优化
int f[maxn];
int h[maxn]; //全名为 height

void Init() {
    
    
	for(int i=1; i<=n; i++) {
    
    
		f[i] = i;
		h[i] = 0;  //令每棵树的高度初始值都为 0 
	}
} 
//合并优化
void merge(int a, int b) {
    
    
	int fa = Find(a);
	int fb = Find(b);
	if(fa==fb) return; 
	
	if(h[fa] < h[fb]) {
    
      //如果元素 a对应的树的高度比 b小 
		f[fa] = fb;  //使元素 a的根指向元素 b的根 
	} else {
    
    
		f[fb] = fa;  //否则让元素 b的根指向元素 a的根 
		if(h[fa] == h[fb]) h[fa]++;
		// 如果两者对应的树的高度相同,则使新生成的树高度 +1 
	}
}

Optimization 2: Path compression

When querying, we need to query from bottom to top along the tree where the element is located, and finally find the root of the tree, indicating that this element and the corresponding element of the root belong to the same group. Because in this query process we will go through many nodes, and if we can point this element directly to the root node, then we can save a lot of query time. At the same time, during the query process, every time we pass through the nodes, we can directly point them to the root node at the same time. By doing this, when we query these nodes, we can quickly know who their roots are.
insert image description here

Code optimization

Optimize the query (Find) function

//查询优化
int Find(int i) {
    
    
	return f[i]==i ? f[i] : f[i] = Find(f[i]);
	//使元素直接指向树的根 
} 

Final code implementation

void Init() {
    
    
	for(int i=0; i<=n; i++) {
    
    
		f[i] = i;
		h[i] = 0;
	}
}
int Find(int i) {
    
    
	return f[i]==i ? f[i] : f[i]=Find(f[i]);
}
void merge(int a, int b) {
    
    
	int fa = Find(a);
	int fb = Find(b);
	if(fa != fb) {
    
    
		if(h[fa] < h[fb]) {
    
    
			f[fa] = fb;
		} else {
    
    
			f[fb] = fa;
			if(h[fa] == h[fb]) h[fa]++;
		}
	}
}

Complexity Analysis

After two optimizations, the efficiency of union search becomes very high. The amortized complexity of one operation on the union of n elements is O(a(n)) (a(n) is the inverse of the Ackerman function), which is less than O(log(n)) before optimization be quick.

classic example

Getting Started with Union Query

Wireless_Network

Union search advanced 1: weighted union search

What is a weighted union search?

Weighted means that an element has additional information. For example, element 1 corresponds to the value 6, and element 2 corresponds to the value 4. The union of these elements with information is called a weighted union.

What is the function of weighted union search?

Weighted union search can calculate the number of elements in each group, and can calculate how many elements in n elements are not added to the group; calculate scores, distances, etc.

Note: The weighted union search needs to be carried out on the basis of path optimization.

classic example

The_Suspects

Union Search Advanced 2: Type Union Search

What is the type of union?

The type union search set is able to divide the union search set into several parts, and each part has a different type.

What is the role of type union?

Type unions can separate the two lineups. For example, divide the good and the bad into two camps.

classic example

food chain

imprison criminals

Reference:
"Challenge Programming Contest"
Path Compression_Union Check

Guess you like

Origin blog.csdn.net/weixin_51250927/article/details/113448263