套路题 并查集合并+统计出答案
#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define mp(a,b) make_pair(a,b)
#define db(a) (cout<<"----"<<a<<endl)
#define pb push_back
#define maxn 10200
int fa[maxn];
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void Union(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy) fa[fy]=fx;
}
struct node{
set<int> s;
int first,siz,total,area;
double avs,ava;
}family[maxn];
struct in{
int person,fa,mo,k;
int child[10];
int num;
int area;
}p[maxn];
bool cmp(node a,node b){
return a.ava!=b.ava?a.ava>b.ava:a.first<b.first;
}
int main(){
int n;cin>>n;
FORP(i,1,maxn-1){
fa[i]=i;
}
FORP(i,1,n){
cin>>p[i].person;
cin>>p[i].fa>>p[i].mo;
if(p[i].fa!=-1) Union(p[i].person,p[i].fa);
if(p[i].mo!=-1) Union(p[i].person,p[i].mo);
cin>>p[i].k;
FORP(j,1,p[i].k){
cin>>p[i].child[j];
Union(p[i].person,p[i].child[j]);
}
cin>>p[i].num>>p[i].area;
}
FORP(i,1,n){
int rt=find(p[i].person);
family[rt].s.insert(p[i].person);
if(p[i].fa!=-1) family[rt].s.insert(p[i].fa);
if(p[i].mo!=-1) family[rt].s.insert(p[i].mo);
FORP(j,1,p[i].k) family[rt].s.insert(p[i].child[j]);
family[rt].total+=p[i].num;
family[rt].area+=p[i].area;
}
int cnt=0;
FORP(i,0,maxn-1){
family[i].siz=family[i].s.size();
if(family[i].siz) family[i].first=*(family[i].s.begin()),cnt++,family[i].avs=family[i].total*1.0/family[i].siz,family[i].ava=family[i].area*1.0/family[i].siz;
}
cout<<cnt<<endl;
sort(family,family+maxn,cmp);
FORP(i,0,maxn-1){
if(family[i].siz){
printf("%04d %d %.3lf %.3lf\n",family[i].first,family[i].siz,family[i].avs,family[i].ava);
}
}
return 0;
}