#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n;
struct DATA{
    int id, fid,mid , k;
    int num,people,area;
    int cid[10];
}data[10001];
int vis[10001] = { 0} ;
int father[10001]  = {0};
struct Node{
    int id;
    double num,area;
    int people;
    int state;
}ans[10001];
bool cmp(Node &a,Node &b){
    if(a.area != b.area) return a.area > b.area;
    else a.num<b.num;
}
int find(int x){
    int a = x;
    while(x != father[x]){
        x = father[x];
    }
    while(a != father[a]){
         int z = a;
         a = father[a];
         father[z]  = x;
    }
    return x;
}
void Union(int a,int b){
    int fa = find(a);
    int fb = find(b);
    if(fa > fb) father[fa] = fb;
    else if(fa < fb) father[fb] = fa;
}
int main()
{
    cin>>n;
    for(int i=0;i<10000;i++)
    father[i] = i;
    for(int i=0;i<n;i++){
        scanf("%d%d%d%d",&data[i].id,&data[i].fid,&data[i].mid,&data[i].k);
         vis[data[i].id] = 1 ;
         if(data[i].fid != -1){
             vis[data[i].fid]  =1 ;
             Union(data[i].id,data[i].fid);
         }
         if(data[i].mid != -1){
             vis[data[i].mid] = 1;
             Union(data[i].id, data[i].mid);
         }
         for(int j=0;j<data[i].k;j++){
             scanf("%d",&data[i].cid[j]);
             vis[data[i].cid[j]]=1;
             Union(data[i].id,data[i].cid[j]);
         }
         scanf("%d%d",&data[i].num,&data[i].area);
    }
    for(int i = 0 ;i < n;i++){ // 遍历所有的父节点 
        int id = find(data[i].id);
        ans[id].id = id;
        ans[id].num +=data[i].num;
        ans[id].area += data[i].area;
        ans[id].state = 1;    
    }
    int cnt = 0;
    for(int i=0;i<10000;i++){
        if(vis[i]){
            ans[find(i)].people++;
        }
        if(ans[i].state)
        cnt++;
    }
    for(int i=0;i<10000;i++)
    if(ans[i].state){
        ans[i].num = ans[i].num*1.0/ans[i].people;
        ans[i].area = ans[i].area*1.0/ans[i].people;
    }
    printf("%d\n",cnt);
    sort(ans,ans+10000,cmp);
    for(int i=0;i<cnt ;i++){
        printf("%04d %d %.3f %.3f\n",ans[i].id,ans[i].people,ans[i].num,ans[i].area);
    }
    
    return 0;
 } 

1.对于输入数据和输出结果分别定义结构体;

2.对于输出数据中的后两项是由前面数据计算出来的,不用单独定义变量;

3.对于离散的点,题中给了范围,对范围内的所有点的父节点都初始化为本身,通过vis数组判断哪些节点出现过;

4.取最小节点编号,可以在合并的时候不断维护根节点为集合中的最小编号节点;

5.直接通过枚举数据来统计每个集合人数不好统计,枚举每个出现的人找到对应的父节点,在父节点上累加人数。