1. 程式人生 > 實用技巧 >PAT - 甲級 - 1114 Family Property

PAT - 甲級 - 1114 Family Property

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\n",v[i].id , v[i].cnt , v[i].avgm , v[i].avgarea);
	}
	return 0;
}