Data structure 5-4-1 and query set

1. Concept

The union search collection is essentially the use of the knowledge of the tree. It is often used for the related representation of the set. It is different from the general binary tree. The union search collection uses the pointer to the parent node, which is convenient for classification and not easy to find the child nodes.

Second, the code implementation

There are mainly three functions for simple union search, initialization, merging and query.

There are many ways to initialize. It can all be initialized to itself, which is equivalent to treating each node as a separate tree in the starting state, and these trees have only one root node, so that they all point to themselves. All can also be initialized to -1. The advantage of this kind of initialization is that the number of nodes in this set can be stored on the top node.

void init()
{
    
    
	for(int i=1;i<=n;i++)
		data[i]=i;
}
//初始化为自己
void init()
{
    
    
	for(int i=1;i<=n;i++)
		data[i]=-1;
}
//初始化为-1

Merge is different according to the way of initialization, and there are subtle differences, but the main idea is the same, compare whether two nodes are in a set, if not, it means that you can merge, use the search function to find the root node of the set, and then let one The root node points to another one, and the merge operation can be completed.

void merge(int x,int y)
{
    
    
	int tx=find(x);
	int ty=find(y);
	if(tx!=ty)
		data[tx]=data[ty];
	//初始化为-1时可以补一句data[ty]+=data[tx],这样数组值的绝对值表示的就是集合中元素的个数
}

According to different initializations, different search end flags should be set. When using initialization as self, the sign of the end of the search is that the value of the corresponding position is equal to its own subscript. When initialized to -1, the sign of the end of the search is that the value of the corresponding position is less than zero.

int find(int x)
{
    
    
	while(data[x]!=x)
		x=data[x];
	return x;
}
//初始化为自己
int find(int x)
{
    
    
	while(data[x]>=0)
		x=data[x];
	return x;
}
int find(int n)
{
    
    
	if(pre[n]==n)
		return n;
	else
		return pre[n]=find(pre[n]);
}
//递归实现

It’s not difficult to find the collection itself. It’s not difficult for seniors when they were engaged in Blue Bridge ACM, just understand the process of searching upwards. The complete code is as follows

#include<bits/stdc++.h>
using namespace std;
int data[1005];
int m,n,choice=0;
void init()
{
    
    
	for(int i=1;i<=n;i++)
		data[i]=i;
}
int find(int x)
{
    
    
	while(data[x]!=x)
		x=data[x];
	return x;
}
void merge(int x,int y)
{
    
    
	int tx=find(x);
	int ty=find(y);
	if(tx!=ty)
		data[tx]=data[ty];
}
int main()
{
    
    
	scanf("%d %d",&m,&n);
	init();
	for(int i=0;i<m;i++)
	{
    
    
		int x,y;
		scanf("%d %d",&x,&y);
		merge(x,y);
	}
	scanf("%d",&choice);
	while(choice!=-1)
	{
    
    
		printf("%d\n",find(choice));
		scanf("%d",&choice);
	}
		 
	return 0;
 } 

Guess you like

Origin blog.csdn.net/weixin_43849505/article/details/107499141