PAT

Nothing to fear


种一棵树最好的时间是十年前,其次是现在!

那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~


人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!

Family Property

考点: 并查集

题目大意

给你一个家庭,家庭成员包括自己的id , 父亲id,母亲id , 以及k个孩子的id,随后给出这个家庭的房产总套数和房产总面积。需要你统计出每一个大家族的房产总面积,和总套数,以及这个大家族总所有人数的个数和这个大家族中编号最小的那个人的ID.

分析

通过分析我们可知将不同的家庭合并至一起相当于多个集合之间进行合并,此时我们优先想到使用并查集进行存储关系,然后对其进行遍历整合排序输出即可

存在一个细节,再进行合并的时候我们需要京一个集合的代表元素设置为这个集合之中的修小的元素以便于我们进行后序的操作。于是Union应该写成这样

void Union(int x , int y)
{
	int A = find(x) , B = find(y);
	if(A > B)f[A] = B;
	else if(A < B)f[B] = A;
}

需要注意的点:

  • 合并的时候需要直接让最小的那一个代号作为树根

完整代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 10005;
int f[N] , n;
bool vis[N];
int find(int k)
{
	if(k == f[k])return k;
	else return f[k] = find(f[k]);
}
void Union(int x , int y)
{
	int A = find(x) , B = find(y);
	if(A > B)f[A] = B;
	else if(A < B)f[B] = A;
}
struct node{
	int id , m , area ,cnt; // cnt表示家庭实际人数
	double avgarea , avgm;
}a[N];
bool cmp(node a, node b)
{
	if (a.avgarea != b.avgarea)
		return a.avgarea > b.avgarea;
	else
		return a.id < b.id;
}
int main()
{
	for(int i = 1;i < N;i ++)f[i] = i,a[i].id = i;
	cin >> n;
	vector<node> v;
	for(int i = 0;i < n;i ++)
	{
		int me , fa , ma , k , child , m ,area;
		cin >> me >> fa >> ma;vis[me] = 1;
		if(fa != -1)Union(me , fa) , vis[fa] = 1;
		if(ma != -1)Union(me , ma) , vis[ma] = 1;
		cin >> k;
		for(int j = 0;j < k;j ++){
			cin >> child;vis[child] = 1;
			Union(me , child);
		}
		cin >> m >> area;
		a[me] = {me , m , area}; //家庭代表
	}
	for(int i = 0;i < N;i++)
	{
		int fa = find(i);
		if(vis[i])a[fa].cnt++;
		if(a[i].id != 0)
		{
			if(i == fa)continue;
			a[fa].m += a[i].m;
			a[fa].area += a[i].area;
		}
	}
	for(int i = 0;i < N;i ++)
	{
		if(vis[i] && i == find(i)){
			a[i].avgarea = a[i].area * 1.0 / a[i].cnt;
			a[i].avgm = a[i].m * 1.0 / a[i].cnt;
			v.push_back(a[i]);
		}	
	}
	sort(v.begin(),v.end(),cmp);
	cout << v.size() << endl;
	for(int i = 0;i < v.size();i ++)
	{
		printf("%04d %d %.3f %.3f
",v[i].id , v[i].cnt , v[i].avgm , v[i].avgarea);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/wlw-x/p/13322765.html