GPLT L2-007 家庭房产 (并查集)
题意:
给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。
思路:
输入和输出各构造一个结构体,利用并查集归并输入,枚举编号进行输出。
#include <bits/stdc++.h> using namespace std; const int M=11000; struct DATA{ int id,fid,mid,num,area; int cid[10]; }data[M]; struct NODE{ int id,people; double num,area; bool flag=false; }ans[M]; int father[M]; bool visit[M]; int Find(int x){ while(x!=father[x]) x=father[x]; return x; } void Union(int A,int B){ int faA=Find(A); int faB=Find(B); if(faA>faB) father[faA]=faB; if(faB>faA) father[faB]=faA; } bool cmp(NODE a,NODE b){ if(a.area==b.area) return a.id<b.id; else return a.area>b.area; } int main() { int n,k,cnt=0;cin>>n; for(int i=0;i<M;i++) father[i]=i; for(int i=0;i<n;i++){ cin>>data[i].id>>data[i].fid>>data[i].mid>>k; visit[data[i].id]=true; if(data[i].fid!=-1){ Union(data[i].fid,data[i].id); visit[data[i].fid]=true; } if(data[i].mid!=-1){ Union(data[i].mid,data[i].id); visit[data[i].mid]=true; } for(int j=0;j<k;j++){ cin>>data[i].cid[j]; Union(data[i].id,data[i].cid[j]); visit[data[i].cid[j]]=true; } cin>>data[i].num>>data[i].area; } for(int i=0;i<n;i++){ int id=Find(data[i].id); ans[id].id=id; ans[id].num+=data[i].num; ans[id].area+=data[i].area; ans[id].flag=true; } for(int i=0;i<M;i++){ if(visit[i]) ++ans[Find(i)].people; if(ans[i].flag) ++cnt; } for(int i=0;i<M;i++){ if(ans[i].flag){ ans[i].num=1.0*ans[i].num/ans[i].people; ans[i].area=1.0*ans[i].area/ans[i].people; } } sort(ans,ans+M,cmp); printf("%d\n",cnt); for(int i=0;i<cnt;i++) printf("%04d %d %.3f %.3f\n", ans[i].id,ans[i].people,ans[i].num,ans[i].area); return 0; }