PAT A1114ファミリープロパティ[互いに素セット]

タイトル説明

Linkは
一人一人の家族や自分の名前に自分の財産を与え、あなたは人口の数、それぞれの家族のために不動産及び不動産席の一人当たりの面積を数えます。まず、家族の最初の行の出力の数(親戚を持っているすべての人が同じファミリーに属します)。一人当たりの世帯人口数曲の住宅エリアの不動産サイクルあたりの家族数の最小値:次の形式でそれぞれの家族のために次に出力情報。前記平均値は小数点以下3桁を維持するために必要。最初に製品ファミリ情報サイズ高一人当たりの出力、結ばれた場合、昇順で出力部材番号。

分析

  • 限り親族があるとして、このコレクションに属する親族のメンテナンスは、それは親が子供をコントロールしていないで、とにかく、のような親族関係があります
    • \(FA [i]は=私は \) 予め要素の明確な数が存在しない場合でも、言って初期化することができ、それはに再循環される(MAXN \)\
    • その後の実装に、接合親族(両親、子供)を入力します\((マージID、XXX) \)
  • \(データ\)しながらデータを受信するアレイ構造\は(\マージ)動作
  • \(ANS \)統計の構造体配列、コードを見て、多くのピットがあること
    • 前にリサイクルされているので、\(MAXN \) とのように、\(VIS \)の配列は、有効なノードをマークされています
    • 同時にプラスで\(フラグ\) 可変マークルート
#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;
}

おすすめ

転載: www.cnblogs.com/doragd/p/11278479.html