1. 程式人生 > 其它 >L3-003 社交叢集 (天梯賽)

L3-003 社交叢集 (天梯賽)

首先一看就知道是並查集 但是其實這個題不簡單

首先要把題目讀清楚 一個集合 a b c 可能a和b b和c分別有交集 但是a和c沒有交集

首先可以想到對擁有同一個興趣愛好的人合併 這樣 a和b b和c 都分別合併了

現在考慮將 ab整體 和 bc整體 合併 每個人作為b 依次將每個人的興趣愛好合並即可

並查集還要統計並查集大小

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=1e3+5;
int fa[maxn],sz[maxn],ans[maxn];
int find(int x){
	if(x!=fa[x])return fa[x]=find(fa[x]);
	return x;
} 
void un(int x,int y){
	int fx=find(x),fy=find(y);
	fa[fx]=fy;
	if(fx!=fy)
	sz[fy]+=sz[fx];
	return;
}
int n,cnt;
int num[maxn],a[maxn][maxn];
vector<int>Q[maxn];
int main(){
	cin>>n;
	for(int i=1;i<maxn;i++)fa[i]=i,sz[i]=1;
	for(int i=1;i<=n;i++){
		cin>>num[i];
		char s;cin>>s;
		for(int j=1;j<=num[i];j++){
			cin>>a[i][j];
			Q[a[i][j]].push_back(i);
		}
	}
	for(int i=1;i<maxn;i++)
	if(Q[i].size())
	for(int j=0;j<Q[i].size()-1;j++)
	un(Q[i][j],Q[i][j+1]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<num[i];j++)
		un(Q[a[i][j]][0],Q[a[i][j+1]][0]);
	for(int i=1;i<=n;i++)
	if(fa[i]==i)
	ans[++cnt]=sz[i];
	sort(ans+1,ans+1+cnt);
	cout<<cnt<<endl;
	cout<<ans[cnt];
	for(int i=cnt-1;i>=1;i--)
	cout<<" "<<ans[i];
     return 0;
}