L3-003. 社交集群
题目链接:https://www.patest.cn/contests/gplt/L3-003
查并集
与L2-007(家庭房产)类似,都是采用了并查集的算法,相对来说这题处理起来更简单一点。这里我维护了最小的h[i],便于查找。
代码如下:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define N 1005 5 using namespace std; 6 int a[N];//存放各组h[k]的最小值 7 int pre[N+1]; 8 int r[N];//存放结果sum 9 void Make(); 10 int Find(int n); 11 void Uion(int x,int y); 12 bool compare(int x,int y){ 13 return x>y; 14 } 15 int main(void){ 16 freopen("in.txt","r",stdin); 17 int n; 18 Make(); 19 scanf("%d",&n); 20 for(int i=0;i<n;++i){ 21 int t,h,Min,p; 22 scanf("%d:",&t); 23 for(int j=0;j<t;++j){ 24 scanf("%d",&h); 25 if(!j){ 26 Min=h; 27 p=h; 28 }else{ 29 Min=min(Min,h); 30 Uion(h,p); 31 } 32 } 33 a[i]=Min; 34 } 35 for(int i=1;i<=N;++i)Find(i); 36 for(int i=0;i<n;++i) 37 r[pre[a[i]]]++; 38 sort(r,r+N,compare); 39 int k; 40 for(k=0;k<N;k++) 41 if(!r[k])break; 42 printf("%d\n",k); 43 printf("%d",r[0]); 44 for(int i=1;i<k;++i) 45 printf(" %d",r[i]); 46 printf("\n"); 47 return 0; 48 } 49 void Make(){ 50 for(int i=0;i<=N;++i) 51 pre[i]=i; 52 } 53 int Find(int n){ 54 if(n!=pre[n])pre[n]=Find(pre[n]); 55 return pre[n]; 56 } 57 void Uion(int x,int y){ 58 int k1=Find(x),k2=Find(y); 59 k1<k2?pre[k2]=k1:pre[k1]=k2; 60 }