并查集,第一种是网上学习的代码,对它进行了排序,快一点,第二种就是普通的并查集。
//非常规并查集 并查集数组存的是这一个数一共有几个点 用负数来表示
#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;
}