团体程序设计天梯赛(L2-007 家庭房产 (25 分))

题目:

思路分析:

求一个家庭相当于求一个连通块 那么直接并查集的思想就行

不过这里我们合并时候把数字最小的当老祖宗 方便

第一次遍历是求房产数 和 面积的和

第二次遍历是求家族的人数

第三次遍历是计算平均值! 

代码实现:

const int MAX=1000010;
struct node{
    int id,people;
    double sum1,sum2;
};
node q1[MAX],q2[MAX];
node ans[MAX];
int Ra[MAX];
int fa[MAX];
int vis[MAX];
int vis1[MAX];
bool cmp(node a,node b){
    if(a.sum2==b.sum2){
        return a.id<b.id;
    }
    return a.sum2>b.sum2;
}
int Find(int x)
{
    int temp = x ;
    while(fa[temp]!=temp)
        temp = fa[temp] ;
    return temp;
}
void add(int x , int y)
{
    int t1 , t2 ;
    t1 = Find(x) ;
    t2 = Find(y) ;
    if(t1 != t2)
    {
        if(t1 > t2)
        {
            fa[t1] = t2 ;
        }
        else fa[t2] = t1 ;
    }
}

//int Find(int x){
//    if(x==fa[x]) return x;
//    return fa[x]==Find(fa[x]);
//}
//void add(int x,int y){
//    int xx=Find(x);
//    int yy=Find(y);
//    if(xx==yy) return;
//    if(xx>yy){
//        fa[xx]=yy;
//    }
//    else {
//        fa[yy]=xx;
//    }
//}
int main(){
    int n,id,f,m,k,son;
    cin>>n;
    for(int i=0;i<MAX;i++)
        fa[i]=i;
    for(int i=0;i<n;i++){
        cin>>id;
        cin>>f>>m;
        vis[id]=1;
        if(f!=-1){
            vis[f]=1;
            add(id,f);
        }
        if(m!=-1){
            vis[m]=1;
            add(id,m);
        }
        cin>>k;
        for(int i=0;i<k;i++){
            cin>>son;
            if(son!=-1){
                vis[son]=1;
                add(id,son);
            }
        }
        cin>>q1[i].sum1;
        cin>>q1[i].sum2;
        q1[i].id=id;
    }
    for(int i=0;i<n;i++){
        
            int t=Find(q1[i].id);
            q2[t].id=t;
            q2[t].sum1+=q1[i].sum1;
            q2[t].sum2+=q1[i].sum2;
        
    }
    for(int i=0;i<MAX;i++){
        if(vis[i]){
            int t=Find(i);
            q2[t].people++;
        }
    }
    int num=0;
    for(int i=0;i<MAX;i++){
        if(vis[i]){
            int t=Find(i);
            if(!vis1[t]){
                vis1[t]=1;
                double xx=q2[t].people;
                ans[num].id=t;
                ans[num].people=int(xx);
                ans[num].sum1=q2[t].sum1*1.0/xx;
                ans[num++].sum2=q2[t].sum2*1.0/xx;
            }
        }
    }
    sort(ans,ans+num,cmp);
    cout<<num<<endl;
    for(int i=0;i<num;i++){
        printf("%04d %d %.3f %.3f\n" , ans[i].id,ans[i].people,ans[i].sum1,ans[i].sum2);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭晋龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值