考察并查集的熟练使用。
const int N=10010;
struct Node
{
int id;
int father,mother;
int k;
int child[6];
}a[1010];
struct Answer
{
int id;
int cnt;
double sets;
double area;
bool operator<(const Answer &W) const
{
if(area != W.area) return area > W.area;
return id < W.id;
}
};
int p[N],cnt[N];
double sets[N],area[N];
bool vis[N];
int n;
int find(int x)
{
if(x != p[x]) p[x]=find(p[x]);
return p[x];
}
void merge(int x,int y)
{
int px=find(x),py=find(y);
if(px < py) swap(px,py);
if(px != py)
{
p[px]=py;
cnt[py]+=cnt[px];
sets[py]+=sets[px];
area[py]+=area[px];
}
}
int main()
{
for(int i=0;i<N;i++) p[i]=i,cnt[i]=1;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i].id>>a[i].father>>a[i].mother;
cin>>a[i].k;
for(int j=0;j<a[i].k;j++) cin>>a[i].child[j];
cin>>sets[a[i].id]>>area[a[i].id];
}
for(int i=0;i<n;i++)
{
vis[a[i].id]=true;
if(~a[i].father)
{
vis[a[i].father]=true;
merge(a[i].id,a[i].father);
}
if(~a[i].mother)
{
vis[a[i].mother]=true;
merge(a[i].id,a[i].mother);
}
for(int j=0;j<a[i].k;j++)
{
vis[a[i].child[j]]=true;
merge(a[i].id,a[i].child[j]);
}
}
int tot=0;
vector<Answer> res;
for(int i=0;i<N;i++)
if(vis[i] && p[i] == i)
{
tot++;
res.pb({i,cnt[i],sets[i]/cnt[i],area[i]/cnt[i]});
}
sort(res.begin(),res.end());
cout<<tot<<endl;
for(int i=0;i<res.size();i++)
{
int id=res[i].id;
printf("%04d %d %.3f %.3f
",id,cnt[id],sets[id]/cnt[id],area[id]/cnt[id]);
}
//system("pause");
return 0;
}