1114 Family Property (25 分)【难度: 中/ 知识点: 并查集】

在这里插入图片描述
https://pintia.cn/problem-sets/994805342720868352/problems/994805356599820288
挺好的一个并查集,先读入然后再处理。注意:在并查集合并的时候选编号小的作为根。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int p[N],people[N],home_cnt[N],st[N],n;
double area[N];
struct node{
    
    int a,b;}temp;
struct family
{
    
    
    int id,cnt;
    double avg,area;
};
vector<node>ve;
vector<family>ans;
bool cmp(family a,family b)
{
    
    
    if(a.area==b.area)
        return a.id<b.id;
    return a.area>b.area;
}
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
int main(void)
{
    
    
    cin>>n;
    for(int i=0;i<N;i++) p[i]=i,people[i]=1;
    for(int i=0;i<n;i++)
    {
    
    
        int id,month,father,k; cin>>id>>month>>father>>k;
        st[id]=1;
        if(month!=-1) ve.push_back({
    
    id,month}),st[month]=1;
        if(father!=-1) ve.push_back({
    
    id,father}),st[father]=1;
        for(int j=0;j<k;j++)
        {
    
    
            int x; cin>>x; st[x]=1;
            ve.push_back({
    
    id,x});
        }
        cin>>home_cnt[id]>>area[id];
    }
    for(int i=0;i<ve.size();i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b;
        int fa=find(a),fb=find(b);
        if(fa!=fb)
        {
    
    
            if(fa>fb) swap(fa,fb);//选小结点作为根
            people[fa]+=people[fb];
            home_cnt[fa]+=home_cnt[fb];
            area[fa]+=area[fb];
            p[fb]=fa;
        }
    }
    for(int i=0;i<N;i++)
        if(st[i]&&p[i]==i)//如果该点存在,且是该集合的根
        {
    
    
            ans.push_back({
    
    i,people[i],home_cnt[i]*1.0/people[i],area[i]/people[i]});
        }
    sort(ans.begin(),ans.end(),cmp);
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)
    printf("%04d %d %.3lf %.3lf\n",ans[i].id,ans[i].cnt,ans[i].avg,ans[i].area);
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_46527915/article/details/121453717
Recommended