算法复习 并查集
并查集是一个实现十分简单的树型数据结构
它的功能在于快速判断两个数据是不是同一个集合 这个数据结构有两个函数 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;
}

浙公网安备 33010602011771号