PTA家庭房产

这篇博客深入探讨了数据结构中的树,并查集的概念和实现,包括路径压缩和按秩合并等优化策略。通过实例展示了如何使用并查集解决实际问题,如求解家庭成员的平均面积和人口统计。此外,文章还涉及了排序算法,用于对信息进行比较和排序。
摘要由CSDN通过智能技术生成
#include<bits/stdc++.h>
using namespace std;

#define MAX 11111
const int INF = 0x3f3f3f3f;
typedef pair<string,double> Pair;
typedef unsigned long long int ull;

typedef struct
{
	int id;
	set<int> ids;
	double sum_people;
	double sum_area;
	double sum_count;
	double ave_count;
	double ave_area;
}Info;

typedef struct
{
	int id;
	int father;
	int mother;
	vector<int> kids;
	double count;
	double area;
}Node;

Node nodes[7*MAX];
Info infos[MAX];
map<int,int> id_slot;
map<int, int> id_pos;

int root[MAX*7];
int n,m;
int i,j,k;

int find_root(int pos)
{
	int i = pos;
	int temp = pos;

	while(root[pos]!=pos)
		pos = root[pos];

	while(root[i] != pos)
	{
		temp = root[i];
		root[i] = pos;
		i = temp;
	}

	return pos;
}

void id_pos_append(int id, int& pos)
{
	if(id == -1)
		return;
	if(id_pos.find(id) == id_pos.end())
	{
		nodes[pos].id = id;
		id_pos.insert(make_pair(id, pos));
		++pos;
	}
}

void root_append(int a, int id)
{
	map<int,int>::iterator p = id_pos.find(id);

	if(p != id_pos.end())
	{
		int b = find_root(p->second);
		if(a != b)
			root[b] = a;
	}

	return;
}

void ids_append(set<int>& ids, int id)
{
	if(id!=-1)
		ids.insert(id);

	return;
}

void change(int n)
{
	int i,j,k;

	for(i=1; i<=n; ++i)
	{
		infos[i].id = *(infos[i].ids.begin());
		infos[i].sum_people = infos[i].ids.size();
		infos[i].ave_area = infos[i].sum_area / infos[i].sum_people;
		infos[i].ave_count = infos[i].sum_count / infos[i].sum_people;
	}

	return;
}

bool cmp(Info& a, Info& b)
{
	if(a.ave_area != b.ave_area)
		return a.ave_area > b.ave_area;

	return a.id < b.id;
}
int main(void)
{
	cin >> n;
	map<int,int>::iterator p;
	map<int,int>::iterator q;

	for(i=0; i<5*MAX; ++i)
		nodes[i].father = nodes[i].mother = nodes[i].id = -1;
	for(i=1; i<=n; ++i)
	{
		cin >> nodes[i].id >> nodes[i].father >> nodes[i].mother >> k;
		for(j=1; j<=k; ++j)
		{
			int temp;
			cin >> temp;
			nodes[i].kids.push_back(temp);
		}
		cin >> nodes[i].count >> nodes[i].area;
		id_pos.insert(make_pair(nodes[i].id, i));
	}

	j = n+1;

	for(i=1; i<=n; ++i)
	{
		id_pos_append(nodes[i].father, j);
		id_pos_append(nodes[i].mother, j);
		for(k=0; k<(int)nodes[i].kids.size(); ++k)
			id_pos_append(nodes[i].kids[k], j);
	}

	for(i=1; i<j; ++i)
		root[i] = i;

	int size = j-1;
	for(i=1; i<=n; ++i)
	{
		int a = find_root(i);

		root_append(a, nodes[i].father);
		root_append(a, nodes[i].mother);

		for(j=0; j<(int)nodes[i].kids.size(); ++j)
			root_append(a, nodes[i].kids[j]);
	}

	for(i=1; i<=size; ++i)
		find_root(i);

	for(i=1; i<=size; ++i)
	{
		if(root[i] == i)
		{
			int size = id_slot.size();
			id_slot.insert(make_pair(root[i], size+1));
		}
	}

	for(i=1; i<=size; ++i)
	{
		q = id_slot.find(root[i]);
		int slot = q->second;

		infos[slot].sum_area += nodes[i].area;
		infos[slot].sum_count += nodes[i].count;

		ids_append(infos[slot].ids, nodes[i].id);
		ids_append(infos[slot].ids, nodes[i].mother);
		ids_append(infos[slot].ids, nodes[i].father);

		for(j=0; j<(int)nodes[i].kids.size(); ++j)
			ids_append(infos[slot].ids, nodes[i].kids[j]);

	}

	size = id_slot.size();

	change(size);
	sort(infos+1, infos+1+size, cmp);

	cout << size << endl;

	for(i=1; i<=size; ++i)
		printf("%04d %.0lf %.3lf %.3lf\n", infos[i].id, infos[i].sum_people, infos[i].ave_count, infos[i].ave_area);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值