5-25 朋友圈

并查集,第一种是网上学习的代码,对它进行了排序,快一点,第二种就是普通的并查集。

//非常规并查集 并查集数组存的是这一个数一共有几个点 用负数来表示 
#include<stdio.h>
#include<string.h>
#define MAX 30010
int a[MAX];
int rank[MAX];
int N,M;
int max;
void init();
int find(int x);
void union_set(int x,int y);
int main()
{
scanf("%d%d",&N,&M);
init();
max = -1;
for(int i=0;i<M;i++){
	int n;
	scanf("%d",&n);
	int temp1,temp2;
	if(n>=1){
		scanf("%d",&temp1);
	}
	for(int j=1;j<n;j++){
		scanf("%d",&temp2);
		union_set(temp1,temp2);
	}
}
printf("%d\n",-max);
 return 0;
}


void init(){
	for(int i=0;i<=N;i++){
		a[i] = -1;
		rank[i] = 0;
	}
}
//递归 
int find(int x){
	if(a[x]>=0){
		a[x] = find(a[x]);
		return a[x];
	}
	else{
		return x;
	}
}
//非递归 
/*int find(int x){
	int temp=x;
	while(a[temp]>=0){
		temp = a[temp];
	}
	int m;
	while(a[x]>=0){
		m = a[x];
		a[x] = temp;
		x = m;
	}
}
*/
void union_set(int x,int y){
	int dx,dy;
	dx = find(x);
	dy = find(y);
	if(dx==dy) return ;
	else{
		if(rank[dx]>rank[dy]){
			a[dx] += a[dy];
			if(a[dx]<max){
				max = a[dx];
			}
			a[dy] = dx;
		}
		else{
			a[dy] += a[dx];
			if(a[dy]<max){
				max = a[dy];
			}
			a[dx] = dy;
			if(rank[dx]==rank[dy]){
				rank[dx]++;
			}
		}
	}
}


#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
int a[30030];
int ans;
int find(int x){
	if(a[x]>=0){
		a[x] = find(a[x]);
		return a[x];
	}
	return x;
}
void union_(int x,int y){
	int tx = find(x);
	int ty = find(y);
	if(tx==ty) return ;
	a[tx] += a[ty];
	a[ty] = tx;
	if(a[tx]<ans)	ans = a[tx];
}

int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;i++){
		a[i] = -1;
	}
	ans = -1;
	for(int i=0;i<m;i++){
		int t,temp,x;
		scanf("%d",&t);
		if(t>=1)	scanf("%d",&temp);
		for(int j=1;j<t;j++){
			scanf("%d",&x);
			union_(temp,x);
		} 
	}
	printf("%d\n",-ans);
	return 0;
}



你可能感兴趣的:(并查集,PTA)