PTA甲级考试真题练习114——1114 Family Property

题目

PTA甲级考试真题练习114——1114 Family Property_第1张图片

思路

并查集
在并查集的过程中进行set和area的累加,最终每一个根上就是总的家庭成员set和area,然后遍历father数组 ,如果发现跟则加入汇总数组,最后排序输出

代码

#include 
#include 
#include 
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);
	}
}

你可能感兴趣的:(PAT甲级考试真题练习)