题目链接:传送门
思路:根据题意首先把所有给出的人记录下来,包括n个id,还有n个id对应的父母和孩子(可能没有房产信息,但需要在求平均的时候占人数),我这里使用结构体存的,没有信息的人的房产信息默认为零,只记录id,(也可以不这样存储,用一个标记数组标记人是否存在也行),然后扫一遍寻找所有家庭,假设此时家庭成员的都满足p[i]=t,则都存在一个ans[t]这个vector数组中,并且把t存储在集合中,最后遍历集合计算每个家庭的人数和房产信息,然后输出。
c++代码:
#include <bits/stdc++.h>
using namespace std;
struct node {
int id , f , m;
double mestate , area;
bool operator < (const node b)const {
return area > b.area || (area == b.area && id < b.id);
}
node(){id = -1;}
node(int a , int b , int c , double d ,double e) :id(a) , f(b) , m(c) , mestate(d) , area(e){}
};
const int maxn = 2e4 + 5 , N = 1e4 + 5;
int p[maxn];
node g[maxn];
vector <node> ans[maxn] , res;
set <int> st;
int num[N];
int mfind(int u) {
return u == p[u] ? p[u] : p[u] = mfind(p[u]);
}
void munion(int x , int y) {
x = mfind(x);
y = mfind(y);
if(x != y) {
p[y] = x;
}
}
int main() {
int n;
scanf("%d" , &n);
for(int i = 0 ; i < N ; i++)p[i] = i;
for(int i = 0 ; i < n ; i++) {
int id , f , m , k;
cin >> id >> f >> m;
if(f != -1) {
if(g[f].id == -1)g[f] = node(f , 0 , 0 , 0 , 0);
munion(id , f);
}
if(m != -1) {
if(g[m].id == -1)g[m] = node(m , 0 , 0 , 0 , 0);
munion(id , m);
}
cin >> k;
while(k--) {
int t;
cin >> t;
if(g[t].id == -1)g[t] = node(t , 0 , 0 , 0 , 0);
munion(id , t);
}
double mestate , area;
scanf("%lf %lf" , &mestate , &area);
g[id] = node(id , f , m , mestate , area);
}
for(int i = 0 ; i < N ; i++) {
if(g[i].id != -1) {
int t = mfind(p[i]);
ans[t].push_back(g[i]);
st.insert(t);
}
}
for(auto it = st.begin() ; it != st.end() ; it++) {
int t = *it;
int cnt = N;
double e = 0 , ar = 0;
for(int j = 0 ; j < ans[t].size() ; j++) {
cnt = min(cnt , ans[t][j].id);
e += ans[t][j].mestate;
ar += ans[t][j].area;
}
e /= ans[t].size(); ar /= ans[t].size();
res.push_back(node(cnt , 0 , 0 , e , ar));
num[cnt] = ans[t].size();
}
sort(res.begin() , res.end());
printf("%d\n" , res.size());
for(int i = 0 ; i < res.size() ; i++) {
printf("%04d %d %.3f %.3f\n" , res[i].id , num[res[i].id] , res[i].mestate , res[i].area);
}
return 0;
}