算法复习 并查集

并查集是一个实现十分简单的树型数据结构

它的功能在于快速判断两个数据是不是同一个集合 这个数据结构有两个函数 find() 和 join().

join() 将x,y合并一个集合

void find(int x,int y){
	int p=find(x); //分别寻找x,y头上的老大
	int q=find(y);
	if(p != q){//说明x,y不是同一个集合 需要合并
		pre[p]=q;//pre[q]=p也可以
	}
	//如果已经是一个集合 就什么都不做
}

find() 寻找头上的老大

首先需要初始化 让每个数字头上的老大先等于自己

for (int i=0;i<n;i++){
    pre[i]=i;
}
int find(int x){
	int p,tmp;
	p=x;
    //不断递归 直到找到老大 即pre[x]=x时
	while(x!=pre[x]){
		x=pre[x];
	}
    //下面为优化操作 (让树结构的深度保持为2 减少时间)
	while(p!=x){
		tmp=pre[p];
		pre[p]=x;
		p=tmp;
	}
	return x;
}

并查集简单的例题
洛谷P1551

代码如下

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,p;
int X,Y;
int pre[5050];
int find(int x){
   int p,tmp;
   p=x;
   while(x!=pre[x]){
   	x=pre[x];
   }
   while(p!=x){
   	tmp=pre[p];
   	pre[p]=x;
   	p=tmp;
   }
     return x;
}
void join(int x,int y){
   int a=find(x),b=find(y);
   if(a!=b){
   	pre[a]=pre[b];
   }
}
int main(){
   for(int i=0;i<5050;i++){
   	pre[i]=i;
   }
   cin >> n >> m >> p;
   while(m--){
   	cin >> X >> Y;
   	join(X,Y);
   }
   while(p--){
   	cin >> X >>Y;
   	if(find(X)!=find(Y)){
   		puts("No");
   	}
   	else {
   		puts("Yes");
   	}
   }
 return 0;
}
posted @ 2020-08-17 16:03  一个经常掉线的人  阅读(65)  评论(0)    收藏  举报