题目
思路
并查集
在并查集的过程中进行set和area的累加,最终每一个根上就是总的家庭成员set和area,然后遍历father数组 ,如果发现跟则加入汇总数组,最后排序输出
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int nmax = 1005;
const int inf = 2147483647;
int father[10010];
struct info {
int sets, area;
}info_array[10010];
struct path {
double avsets, avarea;
int num, minID;
};
vector<path> v;
path p;
bool visited[10010];
bool cmp(const path& a, const path& b) {
if (a.avarea != b.avarea)
return a.avarea > b.avarea;
else
return a.minID < b.minID;
}
int find(int i) {
int j = i;
while (father[j] >= 0) j = father[j];
int t;
for (int k = i; k != j; k = t) {
t = father[k];
father[k] = j;
}
return j;
}
void merge(int i, int j) {
int root1 = find(i);
int root2 = find(j);
if (root1 != root2) {
if (root1 < root2) {
father[root1] += father[root2];
father[root2] = root1;
info_array[root1].sets += info_array[root2].sets;
info_array[root1].area += info_array[root2].area;
}
else {
father[root2] += father[root1];
father[root1] = root2;
info_array[root2].sets += info_array[root1].sets;
info_array[root2].area += info_array[root1].area;
}
}
}
int main()
{
int n;
cin >> n;
fill(father, father + 10010, inf);
for (int i = 0; i < n; ++i) {
int cur, pa1, pa2, childnum;
cin >> cur >> pa1 >> pa2 >> childnum;
vector<int> vec;
if (!visited[cur]) {
visited[cur] = 1;
father[cur] = -1;
}
if (pa1 != -1) {
vec.emplace_back(pa1);
}
if (pa2 != -1){
vec.emplace_back(pa2);
}
for (int j = 0; j < childnum; ++j) {
int tmp; cin >> tmp;
vec.emplace_back(tmp);
}
int sets, area;
cin >> sets >> area;
int root = find(cur);
info_array[root].sets += sets;
info_array[root].area += area;
for (auto& p : vec) {
if (!visited[p]) {
visited[p] = 1;
father[p] = -1;
}
merge(cur, p);
}
}
for (int i = 0; i < 10010; ++i) {
if (father[i] < 0) {
p.minID = i;
p.num = -father[i];
p.avarea = (double)info_array[i].area / p.num;
p.avsets = (double)info_array[i].sets / p.num;
v.emplace_back(p);
}
}
sort(v.begin(), v.end(), cmp);
cout << v.size() << endl;
for (auto& p : v) {
printf("%04d %d %.3lf %.3lf\n", p.minID, p.num, p.avsets, p.avarea);
}
}