2022.1.29 练习 PAT 甲 1107 Social Clusters (原题链接)
并查集,好吧其实我没那么懂,算法笔记上的解法nb,再次反思自己的不开窍。
题解如下:
#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE=1010;
int father[MAX_SIZE];
int isroot[MAX_SIZE]={0};//记录每个结点是否作为某个集合的根结点
int course[MAX_SIZE]={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 Union(int a,int b)
{
int fa=findfather(a);
int fb=findfather(b);
if(fa!=fb)
{
father[fa]=fb;
}
}
void init(int n)
{
for(int i=1;i<=n;i++)
{
father[i]=i;
isroot[i]=0;
}
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
std::ios::sync_with_stdio(false);
int n;
cin>>n;
init(n);
for(int i=1;i<=n;i++)
{
int k;
string s;
cin>>k>>s;
for(int j=0;j<k;j++)
{
int tmp;
cin>>tmp;
if(course[tmp]==0)//如果活动tmp第一次有人喜欢
course[tmp]=i;//令i喜欢活动tmp
Union(i,findfather(course[tmp]));
}
}
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++;
}
cout<<ans<<endl;
sort(isroot+1,isroot+n+1,cmp);
for(int i=1;i<=ans;i++)
{
cout<<isroot[i];
if(i<ans)
cout<<" ";
}
return 0;
}