并查集 pat1107
作者:互联网
#include <iostream>
#include<algorithm>
#include<cstdio>
//并查集1107
using namespace std;
const int N = 1010;
int father[N];
int isRoot[N] ={0};
int corse[N]={0};
//初始化
void init(int n){
for(int i = 1; i <= n; i++){//必须写成i=1!!!
father[i] = i;
isRoot[i] = false;
}
}
//寻找根节点
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 x){//数据太大会炸
// if(x == father[x]) return x;
// else return findFather(x);
//}
bool cmp(int a, int b){
return a>b;
}
//合并
void Union(int a, int b){
int faA = findFather(a);
int faB = findFather(b);
if(faA != faB){
father[faA] = faB;
}
}
int main()
{
freopen("1107.txt","r",stdin);
int n;
cin>>n;
init(n);
for(int i = 1; i <= n; i++){//人们的标号为从1—N
int k;
scanf("%d:",&k);
for(int j = 0; j < k; j++){
int h;
scanf("%d",&h);
if(corse[h] == 0){//即第一个喜欢这个兴趣的人
corse[h] = i;//即 第i 个人为这个兴趣小组的组长
//isRoot[i]= 1;不能写这句//不然会多出来很多节点
//真正的根节点是在合并之后的才是!!!
}
Union(i,findFather(corse[h]));
}
}
for(int i = 1; i <= n;i++){
isRoot[findFather(i)]++;//统计每组人数
}
int num = 0;//组数
for(int i = 1; i<= n;i++){
if(isRoot[i]!=0)
num++;
}
printf("%d\n",num);
sort(isRoot+1,isRoot + n+1,cmp);//因为i 从1开始
for(int i = 1; i <= num; i++){
printf("%d",isRoot[i]);
if(i<num) printf(" ");
else printf("\n");
}
//cout << "Hello world!" << endl;
return 0;
}
标签:faA,pat1107,int,查集,father,faB,include 来源: https://blog.csdn.net/BuGengFeng/article/details/100173416