天梯赛L2-007 【家庭房产】 并查集

题目链接~https://www.patest.cn/contests/gplt/L2-007

分析:emmmmm,初次看题觉得很恶心,神烦这种输入一大堆乱七八糟数据还要求输出浮点数的题TAT

这次的并查集比较高明,合并的时候采取以num更小的为头目,也就是说,合并过程会把尽可能小的作为头目。。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;

struct Node{
	int id;
	int cnt,area;
}node[maxn];

struct Node2{
	int id,num;
	double area,cnt;
	bool flag;
}res[maxn];

int father[maxn];
bool cmp(Node2 a, Node2 b){
	if(a.flag && b.flag)
		return a.id<b.id;
	return a.flag>b.flag;
}
bool cmp2(Node2 a, Node2 b){
	if(a.area == b.area){
		return a.id < b.id;
	}
	return a.area>b.area;
}
void init(){
	for(int i = 0; i<10000; i++){
		father[i] = i;
	}
}
int getF(int x){
	int a = x;
	while(x != father[x]){
		x = father[x];
	}
	while(father[a] != x){
		int tem = father[a];
		father[a] = x;
		a = tem;
	}
	return x;
}
void merge(int a, int b){
	int fa = getF(a);
	int fb = getF(b);
	if(fa < fb){
		father[fb] = fa;
	}
	else {
		father[fa] = fb;
	}
	
}
int main(){
	init(); //初始化不能漏 
	int n,id,m,f,child,k,cnt,area;
	cin>>n;
	for(int i = 0; i<n; i++){
		cin>>id>>m>>f;
		node[i].id = id;
		if(m != -1){
			merge(id, m);
		}
		if(f != -1){
			merge(id, f);
		}
		cin>>k;
		for(int j = 0; j<k; j++){
			cin>>child;
			merge(id, child);
		}
		cin>>cnt>>area;
		node[i].cnt=cnt;
		node[i].area = area;
	}
	for(int i = 0; i<n; i++){
		int cur = node[i].id;
		int mm = getF(cur);
		res[mm].id = mm;
		res[mm].flag = true;
		res[mm].area += node[i].area;
		res[mm].cnt += node[i].cnt; 
	}
	sort(res, res+maxn, cmp);
	for(cnt = 0; cnt<maxn; cnt++){
		if(res[cnt].flag == false)
			break;
	}
	for(int i = 0; i<cnt; i++){
		int total = 0;
		id = res[i].id;
		for(int j = 0; j<10000; j++){
			if(getF(j) == id) total++;
		}
		res[i].num = total;
		res[i].area /= (1.0*total);
	}
	cout<<cnt<<endl;
	sort(res, res+cnt, cmp2);
	for(int i = 0; i<cnt; i++){
		printf("%04d %d %.3lf %.3f\n", res[i].id, res[i].num, res[i].cnt/(1.0*res[i].num), res[i].area);
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值