并查集算法 — 从大数据开发入门到夺门面出!
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#include <algorithm>
using namespace std;
const int N = 1E4;
int n;
vector<int> p(N);
unordered_set<int> ids;
int Find(int x) {
return p[x] ^ x ? p[x] = Find(p[x]) : x;
}
void Union(const int u, const int v) {
p[Find(u)] = p[Find(v)];
}
int main(void) {
// initialize
iota(begin(p), end(p), 0);
scanf("%d", &n);
unordered_map<int, pair<int, int>> infos;
for (int i = 0; i < n; ++i) {
int id, father, mother, k;
scanf("%d %d %d %d", &id, &father, &mother, &k);
ids.emplace(id);
if (father != -1) Union(id, father), ids.emplace(father);
if (mother != -1) Union(id, mother), ids.emplace(mother);
while (k--) {
int child;
scanf("%d", &child);
Union(child, id);
ids.emplace(child);
}
int estate, area;
scanf("%d %d", &estate, &area);
infos[id] = { estate, area };
}
// statistics 统计信息
unordered_map<int, vector<int>> statistics;
for (const auto& id : ids)
statistics[Find(id)].emplace_back(id);
vector<vector<double>> ans;
for (auto&& [_, members] : statistics) {
int total_estate = 0, total_area = 0;
for (const int member : members) {
total_estate += infos[member].first;
total_area += infos[member].second;
}
ans.push_back({
*min_element(begin(members), end(members)),
members.size(),
static_cast<double>(total_estate) / members.size(),
static_cast<double>(total_area) / members.size()}
);
}
// 按人均房产面积降序顺序输出所有家庭信息。
sort(begin(ans), end(ans), [](const auto& a, const auto& b) {
return a[3] > b[3];
});
printf("%d\n", ans.size());
for (const auto& v : ans)
printf("%04d %d %.3f %.3f\n", static_cast<int>(v[0]), static_cast<int>(v[1]), v[2], v[3]);
}