【PAT甲级】1114 Family Property (25分)(并查集)

题意:

输入一个正整数N(<=10000),接着输入N行每行包括一个人的ID和他双亲的ID以及他的孩子数量和孩子们的ID(四位整数包含前导零),还有他所拥有的房产数量和房产面积。输出一共有多少个块(所有有父子关系的点都视为处于同一块),以及每块的元素个数以及平均每人分得的房产数量和房产面积(保留三位小数),输出顺序按照房产面积降序,第二优先以ID升序。

AAAAAccepted code:

  1 #define HAVE_STRUCT_TIMESPEC
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 int ba[10007];
  5 int per[10007];
  6 int sets[10007],area[10007];
  7 int num[10007];
  8 int child[10007];
  9 int find_(int x){
 10     if(ba[x]==x)
 11         return x;
 12 
 13     return ba[x]=find_(ba[x]);
 14 };
 15 typedef struct{
 16     int id,num;
 17     double avgsets,avgarea;
 18 }st;
 19 st ans[10007];
 20 int vis[10007];
 21 int flag[10007];
 22 bool cmp(st a,st b){
 23     if(a.avgarea!=b.avgarea)
 24         return a.avgarea>b.avgarea;
 25     return a.id<b.id;
 26 }
 27 int main(){
 28     //ios::sync_with_stdio(false);
 29     //cin.tie(NULL);
 30     //cout.tie(NULL);
 31     for(int i=0;i<10000;++i)
 32         ba[i]=i,num[i]=1;
 33     int n;
 34     scanf("%d",&n);
 35     for(int i=1;i<=n;++i){
 36         memset(flag,0,sizeof(flag));
 37         int id;
 38         scanf("%d",&id);
 39         int x=10000,y=10000,z=10000;
 40         x=find_(id);
 41         int fa,mo;
 42         scanf("%d%d",&fa,&mo);
 43         if(fa!=-1)
 44             y=find_(fa);
 45         if(mo!=-1)
 46             z=find_(mo);
 47         int root=min(x,y);
 48         root=min(root,z);
 49         int k;
 50         scanf("%d",&k);
 51         int mn=10000;
 52         for(int j=1;j<=k;++j){
 53             scanf("%d",&child[j]);
 54             mn=min(mn,find_(child[j]));
 55             vis[child[j]]=1;
 56         }
 57         int tsets,tarea;
 58         scanf("%d%d",&tsets,&tarea);
 59         sets[x]+=tsets;
 60         area[x]+=tarea;
 61         if(mn<root)
 62             root=mn;
 63         if(x!=root)
 64             flag[x]=1,num[root]+=num[x],sets[root]+=sets[x],area[root]+=area[x];
 65         if(y!=root&&y!=10000&&!flag[y])
 66             flag[y]=1,num[root]+=num[y],sets[root]+=sets[y],area[root]+=area[y];
 67         if(z!=root&&z!=10000&&!flag[z])
 68             flag[z]=1,num[root]+=num[z],sets[root]+=sets[z],area[root]+=area[z];
 69         ba[x]=root;
 70         if(y<10000)
 71             ba[y]=root;
 72         if(z<10000)
 73             ba[z]=root;
 74         for(int j=1;j<=k;++j){
 75             int temp=find_(child[j]);
 76             ba[temp]=root;
 77             if(temp!=root&&!flag[temp]){
 78                 flag[temp]=1;
 79                 num[root]+=num[temp];
 80                 sets[root]+=sets[temp];
 81                 area[root]+=area[temp];
 82             }
 83         }
 84         vis[id]=1;
 85         if(fa!=-1)
 86             vis[fa]=1;
 87         if(mo!=-1)
 88             vis[mo]=1;
 89     }
 90     int cnt=0;
 91     for(int i=0;i<10000;++i){
 92         if(ba[i]==i&&vis[i]){
 93             ans[++cnt].id=i;
 94             ans[cnt].num=num[i];
 95             ans[cnt].avgsets=1.0*sets[i]/num[i];
 96             ans[cnt].avgarea=1.0*area[i]/num[i];
 97         }
 98     }
 99     sort(ans+1,ans+1+cnt,cmp);
100     printf("%d\n",cnt);
101     for(int i=1;i<=cnt;++i){
102         printf("%04d %d %.3lf %.3lf",ans[i].id,ans[i].num,ans[i].avgsets,ans[i].avgarea);
103         if(i<cnt)
104             printf("\n");
105     }
106     return 0;
107 }

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/12300623.html