PAT A1114 Family Property [disjoint-set]

Title Description

Link
given each person's family members and their property in their name, you count the number of the population, the per capita area of real estate and real estate seats for each family. First, the number of the output of the first row of the family (all who have relatives belong to the same family). Then output information for each family in the following format: minimum number of family members per household population number per capita housing area real estate cycle of songs. Wherein the average value required to retain three decimal places. Family First Information Size high per capita output, if tied, the output member numbers in ascending order.

analysis

  • Maintenance of kinship, as long as there is a kinship, belongs to this collection, it is parents do not control a child, anyway, there is kinship like
    • \ (fa [i] = i \) even if there is no clear number of elements in advance, can be initialized to say, that is recycled to the \ (maxn \)
    • Then enter a junction relatives (parents, children), on the implementation of \ (merge (id, xxx) \)
  • With \ (Data \) structured array receiving data while being \ (Merge \) Operation
  • With \ (ans \) structure array of statistics, there are many pit, looking at the code it
    • Because before is recycled to the \ (MAXN \) , so with \ (VIS \) array is marked valid node
    • At the same time plus \ (flag \) variable mark root
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 1e5;

int fa[maxn];
bool vis[maxn];
int n,k,cnt;

struct Data{
    int id, fid, mid, num, area, cid[10];
}data[1005];

struct node {
    int id, cnt;
    double num, area;
    bool flag;
}ans[maxn];

int find(int x){
    int r = x;
    while(x != fa[x]) x = fa[x];
    while(r != fa[r]){
        int t = r;
        r = fa[r];
        fa[t] = x;
    }
    return x;
}

void merge(int x, int y){
    int fx = find(x);
    int fy = find(y);
    if(fx!=fy) fa[max(fx,fy)] = min(fx,fy); //较小编号的作为祖先
}

int cmp(node a, node b) {
    if(a.area != b.area) return a.area > b.area;
    return a.id < b.id;
}

int main() {
    int n, k, cnt = 0;
    scanf("%d", &n);
    for(int i = 0; i < maxn; i++) fa[i] = i; //当结点数未定时也可以初始化
    //用data结构体保存读入的数据,注意data的大小只有n,不是maxn
    for(int i = 0; i < n; i++) {
        scanf("%d %d %d %d", &data[i].id, &data[i].fid, &data[i].mid, &k);
        vis[data[i].id] = true;
        if(data[i].fid != -1) {
            vis[data[i].fid] = true;
            merge(data[i].fid, data[i].id);
        }
        if(data[i].mid != -1) {
            vis[data[i].mid] = true;
            merge(data[i].mid, data[i].id);
        }
        for(int j = 0; j < k; j++) {
            scanf("%d", &data[i].cid[j]);
            vis[data[i].cid[j]] = true;
            merge(data[i].cid[j], data[i].id);
        }
        scanf("%d %d", &data[i].num, &data[i].area);
    }
    //用ans结构体统计信息,只保存根节点
    for(int i = 0; i < n; i++) {
        int id = find(data[i].id);
        ans[id].id = id;
        ans[id].num += data[i].num;
        ans[id].area += data[i].area;
        ans[id].flag = true;
    }
    //统计集合元素个数和根结点数目
    for(int i = 0; i < maxn; i++) {
        if(vis[i])
            ans[find(i)].cnt++;
        if(ans[i].flag)
            cnt++;
    }
    //计算平均
    for(int i = 0; i < maxn; i++) {
        if(ans[i].flag) {
            ans[i].num = (double)(ans[i].num * 1.0 / ans[i].cnt);
            ans[i].area = (double)(ans[i].area * 1.0 / ans[i].cnt);
        }
    }
    sort(ans, ans + maxn, cmp);
    printf("%d\n", cnt);
    for(int i = 0; i < cnt; i++)
        printf("%04d %d %.3f %.3f\n", ans[i].id, ans[i].cnt, ans[i].num, ans[i].area);
    return 0;
}

Guess you like

Origin www.cnblogs.com/doragd/p/11278479.html
Recommended