PAT (Advanced Level) Practice - 1114 Family Property(25 分)

简介: PAT (Advanced Level) Practice - 1114 Family Property(25 分)

题目链接:点击打开链接

题目大意:略。

解题思路:并查集 + STL 大杂烩。注意:并查集中,不能参与统计操作,因为会出现中途连接之前断开的结点,这样之前的计算就会有误差。

AC 代码

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
int pre[maxn], area[maxn], cnt[maxn];
set<int> hst, st[maxn];
set<int>::iterator sit;
unordered_map<int,int> ump;
unordered_map<int,int>::iterator it;
struct peo
{
    int id, num;
    double cnt, area;
}ps[maxn];
void init()
{
    for(int i=0;i<maxn;i++) pre[i]=i;
}
int findx(int x)
{
    return pre[x]==x ? x : pre[x]=findx(pre[x]) ;
}
void join(int x,int y)
{
    int fx=findx(x), fy=findx(y);
    if(fx!=fy) pre[fx]=fy;
}
int cmp(peo p1,peo p2)
{
    if(p1.area==p2.area) return p1.id<p2.id;
    return p1.area>p2.area;
}
int main()
{
    init();
    int n,id,pid1,pid2,k,tid,a,b,oid;
    scanf("%d",&n);
    // 只处理并查集操作,+-操作不能放在这区域,因为可能会出现两个一开始毫无关联,但中途把之前两个关联起来,这样就会有误算
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d%d",&id,&pid1,&pid2,&k);
        oid=id; // 为下面保存 cnt area 用的
        id=findx(id);
        ump[id]=1;
        if(pid1!=-1) join(pid1,id), ump[pid1]=1;
        if(pid2!=-1) join(pid2,id), ump[pid2]=1;
        while(k--) scanf("%d",&tid), join(tid,id), ump[tid]=1;
        scanf("%d%d",&a,&b);
        cnt[oid]=a;
        area[oid]=b;
    }
    for(it=ump.begin(); it!=ump.end(); it++)
    {
        id=findx(it->first);
        st[id].insert(it->first); // 利用 key 自动排序,筛选编号最小
        hst.insert(id); // 收集每个家庭的祖先结点
        if(id!=it->first)
            cnt[id]+=cnt[it->first],
            area[id]+=area[it->first];
    }
    int l=0;
    for(sit=hst.begin();sit!=hst.end();sit++)
    {
        ps[l].id=*(st[*sit].begin());
        ps[l].num=st[*sit].size();
        ps[l].cnt=cnt[*sit]*1.0/ps[l].num;
        ps[l].area=area[*sit]*1.0/ps[l].num;
        l++;
    }
    sort(ps,ps+l,cmp);
    printf("%d\n",l);
    for(int i=0;i<l;i++)
        printf("%04d %d %.3f %.3f\n",ps[i].id,ps[i].num,ps[i].cnt,ps[i].area);
    return 0;
}
目录
相关文章
PAT (Advanced Level) Practice - 1045 Favorite Color Stripe(30 分)
PAT (Advanced Level) Practice - 1045 Favorite Color Stripe(30 分)
83 0
PAT (Advanced Level) Practice - 1045 Favorite Color Stripe(30 分)
|
存储
PAT (Advanced Level) Practice - 1126 Eulerian Path(25 分)
PAT (Advanced Level) Practice - 1126 Eulerian Path(25 分)
119 0
PAT (Advanced Level) Practice - 1147 Heaps(30 分)
PAT (Advanced Level) Practice - 1147 Heaps(30 分)
101 0
PAT (Advanced Level) Practice - 1095 Cars on Campus(30 分)
PAT (Advanced Level) Practice - 1095 Cars on Campus(30 分)
115 0
PAT (Advanced Level) Practice - 1026 Table Tennis(30 分)
PAT (Advanced Level) Practice - 1026 Table Tennis(30 分)
112 0
PAT (Advanced Level) Practice - 1091 Acute Stroke(30 分)
PAT (Advanced Level) Practice - 1091 Acute Stroke(30 分)
85 0
PAT (Advanced Level) Practice - 1130 Infix Expression(25 分)
PAT (Advanced Level) Practice - 1130 Infix Expression(25 分)
109 0
|
存储 测试技术
PAT (Advanced Level) Practice - 1131 Subway Map(30 分)
PAT (Advanced Level) Practice - 1131 Subway Map(30 分)
94 0
PAT (Advanced Level) Practice - 1053 Path of Equal Weight(30 分)
PAT (Advanced Level) Practice - 1053 Path of Equal Weight(30 分)
105 0
PAT (Advanced Level) Practice - 1139 First Contact(30 分)
PAT (Advanced Level) Practice - 1139 First Contact(30 分)
97 0