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;
}

 

posted @ 2020-03-16 22:30  Kanoon  阅读(138)  评论(0编辑  收藏  举报