解题思路:使用并查集去判断是否属于一个大家庭,以及确定大家庭里的人数
#include<bits/stdc++.h>
using namespace std;
typedef struct Person{//小家庭
int id;
double area;//面积
int sum;//套数
}Person;
typedef struct total{//大家庭
int id;//大家庭中的最小编号
int people=0;人数
double sum=0;//套数
double area=0;//面积
bool flag=false;确定该家庭是否存在
}total;
int father[10010];
int find(int x){
while(x!=father[x])//判断是否属于一个大家庭
x=father[x];
return x;
}
void uniont(int a,int b){//合并小家庭
int fa=find(a),fb=find(b);
if(fa<fb)
father[fb]=fa;
else
father[fa]=fb;
}
bool cmp(total a, total b){//输出要求进行排序
if(a.area!=b.area)
return a.area>b.area;
else
return a.id<b.id;
}
int main(){
int n,mid,fid,k,count=0;
int exit[10001];//记录每个活着的人
memset(exit,0,sizeof(exit));
for(int i=0;i<10001;i++)
father[i]=i;
cin>>n;
Person p[n];
total t[10001];
for(int i=0;i<n;i++){
cin>>p[i].id>>fid>>mid>>k;
exit[p[i].id]=1;
if(fid!=-1){
exit[fid]=1;
uniont(p[i].id,fid);
}
if(mid!=-1){
exit[mid]=1;
uniont(p[i].id,mid);
}
for(int j=1;j<=k;j++){
int kid;
cin>>kid;
exit[kid]=1;
uniont(p[i].id,kid);
}
cin>>p[i].sum>>p[i].area;
}
for(int i=0;i<n;i++){
t[find(p[i].id)].sum+=p[i].sum;
t[find(p[i].id)].area+=p[i].area;
t[find(p[i].id)].flag=true;
t[find(p[i].id)].id=find(p[i].id);
}
for(int i=0;i<10001;i++){
if(exit[i]==1)
t[find(i)].people++;
}
for(int i=0;i<10001;i++){
if(t[i].flag==true)
count++;
}
cout<<count<<endl;;
for(int i=0;i<10001;i++){
if(t[i].flag==true){
t[i].sum=t[i].sum/t[i].people;
t[i].area=t[i].area/t[i].people;
}
}
sort(t,t+10001,cmp);
for(int i=0;i<count;i++){
printf("%04d ",t[i].id);
printf("%d ",t[i].people);
printf("%.3lf ",t[i].sum);
printf("%.3lf\n",t[i].area);
}
}