暑假集训——并查集

并查集的最基本的作用是查找一个元素是不是跟另一个元素在同一个集合内(这个集合是由集合中的某一个元素为表识)通过这两个对这两个元素分别进行查找这个元素所在的集合的标识元素,如果标识元素相同,那么这两个元素就是在同一个集合内,如果不相同就不在一个集合内。同时还可以把这两个不相同的元素连在一起,只要把其中一个集合的标识元素记为另一个元素的前驱结点即可


pre[maxn]//用来记录每个值的父节点,如果使用了压缩路径,那么这个父节点就变成了根节点,也就是一个集合的标识元素所在的位置 
void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy) pre[fx]=fy;
}

int find(int x)  //压缩路径法查找,从而使得每一个点的上一个点指的都是根节点 
{
	if(pre[x] == x) return  x;
	
	int  r    = pre[x] ;
	
	pre[x] = find( pre[x] );//这样做的好处是不仅为以后找元素所在集合的标识元素提速,、
							//而且可以利用这个递归过程来实现很多东西,在很多题中,都是需要在这个递归过程来计算一些东西 
	return  pre[x];
} 
int find(int x)//最普通的方法,有时会很玄学的报错;这时可以试试第一个方法 
{
	int r=x;
	
	while(pre[r]!=r)
	
		r = pre[r];
		
	return	r;
} 

关于并查集可以有很多应用,在处理修路问题,若已知有几个点之间已经有路修通,然而还剩n个点没修,问最小的修路数时,就可以使用并查集的思想,因为那些已经修好的路,一定是一段一段的,那么那几段公里可以看成几个集合,然后去计算有几个集合就可以,病人感染会被隔离,一个隔离区就是一个集合,类似的还有很多。。

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/81712879