L2-007 家庭房产 (25分)

  1. Problem:
    https://pintia.cn/problem-sets/994805046380707840/problems/994805068539215872
  2. tags:
    并查集 细节
  3. Mean:
    如题
  4. Solution
    读入的时候就做并查集的查找,并把所有人都修改为最小的那个.然后再遍历一次记录数据,最后排序输出
  5. Mistakes
    1.并查集操作要find(i),例如修改祖先,不能是fa[x]=Min,要,fa[find(x)]=Min.因为这样才能整体修改,虽然道理很简单,但是经常会写忘记掉.
    2.数据读入的时候,先读入ID,后面按ID填.一开始顺手按I填了,最后数据全是0,debug半天
  6. Grains
    代码写的太丑了,主要是这题恶心的不行.不想改了.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N =1e5+10;
const ll mod=1e9;
int n,fa[10003];
struct node{
    int id,f,m,kids,house;
    int k[10],area;
}p[N];
struct Node{
    int id,peo;
    double home,area;
    bool operator<(const Node b){
        if(area==b.area) return id<b.id;
        return area > b.area;
    }
}P[10003];
int find(int x){
    if(x==-1 || fa[x]==-1) return x;
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x];
}
int vis[10003];
int home[10004];
int area[10004];
int main(){
    cin>>n;
    memset(fa,-1,sizeof(int)*1e4+2);
    for(int i=1;i<=n;i++){
        int Min = 1e7+3,T;
        cin>>T;
        p[T].id = T;
        cin>>p[T].f>>p[T].m>>p[T].kids;
        for(int j=0;j<p[T].kids;j++){
            cin>>p[T].k[j];
            Min = min(Min,find(p[T].k[j]));
        } 
        cin>>p[T].house>>p[T].area;
        if(find(p[T].id)!=-1) Min = min(Min,find(p[T].id));
        if(find(p[T].f)!=-1) Min = min(Min,find(p[T].f));
        if(find(p[T].m)!=-1) Min = min(Min,find(p[T].m));
        fa[find(p[T].id)]=fa[find(p[T].f)]=fa[find(p[T].m)] = find(Min);
        for(int j=0;j<p[T].kids;j++) fa[find(p[T].k[j])] = find(Min);
    }
    int cnt = 0;
    for(int i=0;i<10000;i++)
        if(fa[i]!=-1){
            home[find(i)]+=p[i].house;
            area[find(i)]+=p[i].area;
            vis[find(i)]++; 
        }
    for(int i=0;i<10000;i++){
        if(vis[i]){
            P[cnt].id = i;
            P[cnt].peo = vis[i];
            P[cnt].area = area[i]*1.0/(vis[i]*1.0);
            P[cnt].home = home[i]*1.0/(vis[i]*1.0);
            cnt++;
        }
    }
    cout<<cnt<<endl;
    sort(P,P+cnt);
    for(int i=0;i<cnt;i++){
        printf("%04d %d %.3lf %.3lf\n",P[i].id,P[i].peo,P[i].home,P[i].area);
    }
}   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值