【题解】【AcWing】1604. 家产

142 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1604. 家产

原题传送:AcWing 1604. 家产

这次,需要你帮我们整理关于家庭财产方面的数据。

给定每个人的家庭成员以及他/她自己名字下的不动产(地产)信息,我们需要知道每个家庭的成员数,以及人均不动产面积和人均房产套数。

输入格式

第一行包含整数 NN

接下来 NN 行,每行包含一个拥有房产的人员的信息,格式如下:

ID Father Mother k Child_1 ... child_k M_estate Area

其中 ID 是每个人的独一无二的 44 位数标识号,FatherMother 是这个人的父母的 ID 号(父母去世则用 -1 代替), kk 是孩子数量,Child_i 是孩子的IDM_estate 是其名下房产数量,Area 是其名下房产的总面积。

输出格式

每行输出一个家庭的相关房产信息,格式如下:

ID M AVG_sets AVG_area

其中 ID 是家庭成员中编号最小的成员编号,M 是家庭成员数,AVG_sets 是人均房产套数,AVG_area 是人均房产面积。

两个平均数都要保留三位小数。

按人均房产面积降序顺序输出所有家庭信息。

当存在人均房产面积相同的情况时,按 ID 升序顺序排序。

数据范围

1N10001 \le N \le 1000 , 0k50 \le k \le 5 每个人名下房产不超过 100100 套, 每个人名下房产总面积不超过 5000050000

输入样例1:

10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100

输出样例:

3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

思路:

将输入信息转成房产人员和父亲、母亲或孩子的表示一对一关系的边,然后遍历将每对关系的大编号合并至小编号,最后将最小编号家庭成员及信息存入vector排序输出。

题解:

#include<bits/stdc++.h>

using namespace std;

const int N = 10010;

int n;
int p[N], c[N], hc[N], ha[N];
bool st[N];

struct Edge
{
	int a, b;
}e[N];

struct Family
{
	int id, c, hc, ha;
	
	bool operator< (const Family &t) const
	{
		if(ha * t.c != t.ha * c)
			return ha * t.c > t.ha * c;
		return id < t.id;
	}
};

int find(int x)
{
	if(p[x] != x)
		p[x] = find(p[x]);
	return p[x];
}

int main()
{	
	cin >> n;

	int m = 0;
	for(int i = 0; i < n; i++)
	{
		int id, father, mother, k;
		cin >> id >> father >> mother >> k;
		
		st[id] = true;
		if(father != -1)
			e[m++] = {id, father};
		if(mother != -1)
			e[m++] = {id, mother};
		for(int j = 0; j < k; j++)
		{
			int son;
			cin >> son;
			e[m++] = {id, son};
		}
		
		cin >> hc[id] >> ha[id]; 
	}
		
	for(int i = 0; i < N; i++)
		p[i] = i, c[i] = 1;
	for(int i = 0; i < m; i++)
	{
		int a = e[i].a, b = e[i].b;
		st[a] = st[b] = true;
		int pa = find(a), pb = find(b);
		if(pa != pb)
		{
			if(pb > pa)
				swap(pa, pb);
			c[pb] += c[pa]; 
			hc[pb] += hc[pa]; 
			ha[pb] += ha[pa]; 
			p[pa] = pb;
		}
	}
	
	vector<Family> family;
	for(int i = 0; i < N; i++)
	{
		if(st[i] && p[i] == i)
		{
			family.push_back({i, c[i], hc[i], ha[i]});
		}
	}
	
	sort(family.begin(), family.end());
	
	cout << family.size() << endl;
	for(auto f :family)
		printf("%04d %d %.3lf %.3lf\n", f.id, f.c, (double)f.hc / f.c, (double)f.ha / f.c);
	
	return 0;
}