[patl2-007]家庭房产

题目大意:求并查集中集合的个数,及每个集合的详细信息

解题关键:只要不进行unite,集合的根是不会变化的。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
struct node{
    int id,cnt,area;
}pe[10002];
struct nod{
    int id,num,cnt,area;
    double avcnt,avar;
}pa[10002];
bool vis[10002];
int par[10002];
int find1(int x){
    if(x==par[x]) return x;
    else return par[x]=find1(par[x]);
}
bool cmp(nod x,nod y){
    if(x.avar==y.avar) return x.id<y.id;
    else return x.avar>y.avar;
}
void unite(int x,int y){
    x=find1(x);
    y=find1(y);
    if(x==y) return;
    else par[x]=y;//为什么这里改变一下会有变化???
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<10002;i++){
        par[i]=i;
    }
    for(int i=0;i<n;i++){
        int t1,t2,t3;
        scanf("%d%d%d",&t1,&t2,&t3);
        vis[t1]=true;
        if(t2!=-1){
            unite(t1, t2);
            vis[t2]=true;
        }
        if(t3!=-1){
            unite(t1,t3);
            vis[t3]=true;
        }
        int k;
        scanf("%d",&k);
        for(int j=0;j<k;j++){
            int temp;
            scanf("%d",&temp);
            unite(t1,temp);
            vis[temp]=true;
        }
        pe[i].id=t1;
        int t4,t5;
        scanf("%d%d",&t4,&t5);
        pe[i].cnt=t4;
        pe[i].area=t5;
    }
    
    
    
    for(int i=0;i<n;i++){
        int id=find1(pe[i].id);
        //id=find1(id);
        pa[id].cnt+=pe[i].cnt;
        pa[id].area+=pe[i].area;
        // pa[id].num++;
    }
    
    for(int i=0;i<=9999;i++){//这里是核心
        if(vis[i]){
            //int t=par[i]=find1(i);
            int t=find1(i);
            if(!pa[t].num){
                pa[t].id=i;
            }
            pa[t].num++;
            pa[t].avar=pa[t].area*1.0/pa[t].num;//这里其实是重复覆盖的
            pa[t].avcnt= pa[t].cnt*1.0/pa[t].num;
        }
    }
    
    
    
    sort(pa,pa+10000,cmp);
    int ans=0;
    for(int i=0;i<10000;i++){
        if(pa[i].num){
            ans++;
        }
        //else break;
    }
    printf("%d\n",ans);
    for(int i=0;i<ans;i++){
        if(pa[i].num){
            printf("%04d %d %.3lf %.3lf\n",pa[i].id,pa[i].num,pa[i].avcnt,pa[i].avar);
        }
    }
    
}

 

posted @ 2018-03-07 23:46  Elpsywk  阅读(361)  评论(0编辑  收藏  举报