一、题目分析
1. 翻译
register on:注册
cluster:集群
2. 分析
1)相同爱好的人为一个集群,原来我的错误理解:
正确的应该是:
因此想到用并查集,每个爱好的第一个人为这个集合的“祖宗”。
2)根据《算法笔记》中所说,是否进行路径压缩都可以。
3)注意if
和while
的使用,最近总是搞混。
二、代码解析
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <cctype>
#include <unordered_map>
#include <stack>
#include <queue>
using namespace std;
const int N=1010;//注意加const
int cluster[N]= {0};
int isRoot[N]= {0};
int father[N];
void init(int n) {
for(int i=1; i<=n; i++) {
father[i]=i;
}
}
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 _union(int a,int b) {
int fa=findfather(a);
int fb=findfather(b);
if(fa!=fb) {//是if!不是while!
father[fa]=fb;
}
}
bool cmp(int a,int b) {
return a>b;
}
int main() {
int n,k,h;
scanf("%d",&n);
init(n);//初始化每个结点
for(int i=1; i<=n; i++) {
scanf("%d:",&k);
for(int j=0; j<k; j++) { //每个活动
scanf("%d",&h);
if(cluster[h]==0) { //h爱好的第一个人
cluster[h]=i;
}
_union(i,findfather(cluster[h]));
}
}
for(int i=1; i<=n; i++) {
isRoot[findfather(i)]++;
}
sort(isRoot+1,isRoot+n+1,cmp);
int sum=0;
for(int i=1; i<=n; i++) {
if(isRoot[i]!=0) sum++;
}
cout<<sum<<endl;
for(int i=1; i<=sum; i++) {
cout<<isRoot[i];
if(i!=sum) cout<<" ";
}
return 0;
}
三、我的疑问
无
如果喜欢我的博客,欢迎点赞、评论、收藏~~谢谢
( * ^ ▽ ^ * ) ~