L3-003 社交叢集 (天梯賽)
阿新 • • 發佈:2022-04-20
首先一看就知道是並查集 但是其實這個題不簡單
首先要把題目讀清楚 一個集合 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; }