Day 45 算法笔记之提高篇(3)9.6 并查集

目录

1.定义

2.初始化

3.查找

4.合并

5.优化的查找

6.好朋友

7.Social Clusters


1.定义

int father[N];

2.初始化

for(int i=1;i<N;i++){
	father[i] = i;
}

3.查找

int findfather(int x){
	while(x!=father[x]){
		x=father[x];
	}
	return x;
}

int findfather(int x){
	if(x==father[x]) return x;
	else return findfather(father[x]);
}

4.合并

void union(int a,int b){
	int faa=findfather(a);
	int fab=findfather(b);
	if(faa!==fab){
		father[faa] = fab;
	}
}

5.优化的查找

int findfather(int x){
	int a= x;
	while(x!=father[x]){
		x=father[x];
	}
	while(a!=father[a]){
		int z = a;
		a=father[a];
		father[z] = x;
	}
	return x;
}

int findfather(int v){
	if(v==father[v]) return v;
	else{
		int f=findfather(father[v]);
		father[v] = f;
		return f;
	}
}

6.好朋友

#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int N = 110;
int father[N];
bool isroot[N];

int findfather(int x){
	int a= x;
	while(x!=father[x]){
		x=father[x];
	}
	while(a!=father[a]){
		int z=a;
		a=father[a];
		father[z] = x;
	}
	return x;
}

void unions(int a,int b){
	int faa=findfather(a);
	int fbb=findfather(b);
	if(faa!=fbb){
		father[faa] = fbb;
	}
}

void init(int n){
	for(int i=1;i<=n;i++){
		father[i] = i;
		isroot[i] = false;
	}
}

int main(){
	
	int n,m,a,b;
	scanf("%d",&n,&m);
	init(n);
	for(int i=0;i<m;i++){
		scanf("%d%d",&a,&b);
		unions(a,b);
	}
	for(int i=1;i<=n;i++){
		isroot[findfather(i)]=true;
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans+=isroot[i];
	}
	printf("%d\n",ans);
	
	return 0;
}

7.Social Clusters

#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int N = 1010;
int father[N];
int isroot[N] = {0};
int course[N] = {0};

int findfather(int x){
	int a = x;
	while(x!=father[x]){
		x = father[x];
	}
	while(a!=father[a]){
		int z = a;
		a=father[a];
		father[z] = x;
	}
	return x;
}

void unions(int a,int b){
	int faa=findfather(a);
	int fab=findfather(b);
	if(faa!=fab){
		father[faa] = fab;
	}
}

void init(int n){
	for(int i=1;i<=n;i++){
		father[i] = i;
		isroot[i] = false;
	}
}

bool cmp(int a,int b){
	return a>b;
}

int main(){
	
	int n;
	scanf("%d",&n);
	init(n);
	int k,h;
	for(int i=1;i<=n;i++){
		scanf("%d:",&k);
		for(int j=0;j<k;j++){
			scanf("%d",&h);
			if(course[h]==0){
				course[h] = i;
			}
			unions(i,findfather(course[h]));
		}
	}
	
	for(int i=1;i<=n;i++){
		isroot[findfather(i)]++;
	}
	
	int ans=0;
	for(int i=1;i<=n;i++){
		if(isroot[i]!=0){
			ans++;
		}
	}
	
	printf("%d\n",ans);
	sort(isroot+1,isroot+n+1,cmp);
	for(int i=1;i<=ans;i++){
		printf("%d",isroot[i]);
		if(i<ans) printf(" ");
	}
	
	
	return 0;
}

おすすめ

転載: blog.csdn.net/aixiaoxiao13/article/details/121475195