题目大意:
给出n个人的家庭信息id, f_id, m_id, c_num, child1,child2… ,num, area。
分别代表这个人的id,父亲的id,母亲的id,子女的个数,子女id,总共拥有的房产数,房产的总面积。
我们要求出总共有几个不同的家庭,并输出每个家庭中id最小成员的id,家庭成员数,平均房产数,平均房产面积。
思路:
模拟+并查集的思路。
代码如下:
//并查集+离线
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdio.h>
#define INF 0x3f3f3f3f
using namespace std;
int n;
int fa[10005];
int flag[10005]={0};
struct family{
int min_id;
int sum;//总人数
int num,area;//总房产数,总面积
double avg_num,avg_area;//平均房产数,平均面积
family(){
num=area=sum=0;
min_id=INF;
}
};
int findfather(int x){
if(x!=fa[x]){
return findfather(fa[x]);
}else{
return x;
}
}
void _union(int a,int b){
int aa=findfather(a);
int bb=findfather(b);
if(aa!=bb){
fa[aa]=bb;
}
}
vector<family> vec;
bool cmp(family a,family b){
if(a.avg_area>b.avg_area){
return true;
}else if(a.avg_area==b.avg_area){
return a.min_id<b.min_id;
}
return false;
}
int main(){
for(int i=0;i<10005;i++){
fa[i]=i;
}
cin>>n;
vec.resize(10005);
int id[1005],f_id[1005],m_id[1005],k[1005],c_id[1005][6],num[1005],area[1005];
for(int i=0;i<n;i++){
cin>>id[i]>>f_id[i]>>m_id[i]>>k[i];
if(f_id[i]!=-1){
_union(id[i],f_id[i]);
}
if(m_id[i]!=-1){
_union(id[i],m_id[i]);
}
for(int j=0;j<k[i];j++){
cin>>c_id[i][j];
_union(id[i],c_id[i][j]);
}
cin>>num[i]>>area[i];
}
for(int i=0;i<n;i++){
int sum=0;
int father=findfather(id[i]);
if(findfather(id[i])==id[i]){
if(flag[id[i]]==0){
sum++;
}
}
if(findfather(id[i])!=id[i]){
if(flag[id[i]]==0){
sum++;
}
}
flag[id[i]]=1;
if(f_id[i]!=-1){
if(findfather(f_id[i])!=f_id[i]){
if(flag[f_id[i]]==0){
sum++;
}
}
if(findfather(f_id[i])==f_id[i]){
if(flag[f_id[i]]==0){
sum++;
}
}
flag[f_id[i]]=1;
}
if(m_id[i]!=-1){
if(findfather(m_id[i])!=m_id[i]){
if(flag[m_id[i]]==0){
sum++;
}
}
if(findfather(m_id[i])==m_id[i]){
if(flag[m_id[i]]==0){
sum++;
}
}
flag[m_id[i]]=1;
}
for(int j=0;j<k[i];j++){
if(findfather(c_id[i][j])!=c_id[i][j]){
if(flag[c_id[i][j]]==0){
sum++;
}
}
if(findfather(c_id[i][j])==c_id[i][j]){
if(flag[c_id[i][j]]==0){
sum++;
}
}
flag[c_id[i][j]]=1;
}
if(id[i]<vec[father].min_id){
vec[father].min_id=id[i];
}
if(f_id[i]!=-1&&f_id[i]<vec[father].min_id){
vec[father].min_id=f_id[i];
}
if(m_id[i]!=-1&&m_id[i]<vec[father].min_id){
vec[father].min_id=m_id[i];
}
for(int j=0;j<k[i];j++){
if(c_id[i][j]<vec[father].min_id){
vec[father].min_id=c_id[i][j];
}
}
vec[father].sum+=sum;
vec[father].num+=num[i];
vec[father].area+=area[i];
}
int tot=0;
for(int i=0;i<10005;i++){
if(vec[i].sum!=0){
tot++;
vec[i].avg_num=(double)vec[i].num/(double)vec[i].sum;
vec[i].avg_area=(double)vec[i].area/(double)vec[i].sum;
}
}
cout<<tot<<endl;
sort(vec.begin(),vec.end(),cmp);
for(int i=0;i<10005;i++){
if(vec[i].sum!=0){
printf("%04d %d %.3lf %.3lf",vec[i].min_id,vec[i].sum,vec[i].avg_num,vec[i].avg_area);
cout<<endl;
}
}
return 0;
}