PAT A 1114. Family Property (25)

#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
/*可用DFS解决,图结点可对于每一个人建立一个结点,房子套数和总面积可初始为0,使用链表法进行建图。然后再进行DFS,每个连通域作为一个家庭。*/
struct person{//存储每个人的信息
	int no;
	vector<int> fmembers;
	double set=0.0,area=0.0;
};

struct family{//存储每个家庭的信息
	int no,sum_of_ple;
	double avg_set,avg_areas;
	family()=default;
	family(int x,int y,double a,double b){
		no=x,sum_of_ple=y,avg_set=a,avg_areas=b;
	}
	bool operator<(const family &a)const{
		if(avg_areas!=a.avg_areas)return avg_areas>a.avg_areas;
		return no<a.no;
	}
};

vector<family> res;
vector<int> allple;//用于记录本人的id,可省下无效结点的遍历
person ples[10000];
bool visited[10000]={false};
const int INF=1<<30;


void DFS(const int &v,int &minid,int &sum_of_ple,double &set,double &area){
	if(!visited[v]){
		visited[v]=true;
		if(minid>v)minid=v;
		++sum_of_ple;
		set+=ples[v].set,area+=ples[v].area;
		for(int c:ples[v].fmembers){
			if(!visited[c])DFS(c,minid,sum_of_ple,set,area);
		}
	}
}

void DFS_traverse(){
	for(int c:allple){
		if(!visited[c]){
			family tmp(INF,0,0.0,0.0);//对每个家庭,最小序号初始为无穷大,人数初始为0,房子和面积都初始为0
			DFS(c,tmp.no,tmp.sum_of_ple,tmp.avg_set,tmp.avg_areas);
			tmp.avg_areas/=tmp.sum_of_ple;
			tmp.avg_set/=tmp.sum_of_ple;
			res.push_back(tmp);
		}
	}
}

int main(void){
	//freopen("in.log","r",stdin);
	int n;
	scanf("%d",&n);
	while(n--){//建图
		int id,pid1,pid2,childn;
		scanf("%d%d%d%d",&id,&pid1,&pid2,&childn);
		allple.push_back(id);
		if(pid1!=-1){
			ples[id].fmembers.push_back(pid1);
			ples[pid1].fmembers.push_back(id);
		}
		if(pid2!=-1){
			ples[id].fmembers.push_back(pid2);
			ples[pid2].fmembers.push_back(id);
		}
		while(childn--){
			int childid;
			scanf("%d",&childid);
			ples[id].fmembers.push_back(childid);
			ples[childid].fmembers.push_back(id);
		}
		scanf("%lf%lf",&ples[id].set,&ples[id].area);
	} //建图结束
	DFS_traverse();
	sort(res.begin(),res.end());
	printf("%d\n",res.size());
	for(family c:res){
		printf("%04d %d %.3lf %.3lf\n",c.no,c.sum_of_ple,c.avg_set,c.avg_areas);
	}
	return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值