並查集經典應用場景

時光丨荏苒發表於2019-03-10

例1、家庭財產問題

題目描述

給定每個人的家庭成員和其自己名下的房產,請你統計出每個家庭的人口數、人均房產面積及房產套數。

輸入格式:
輸入第一行給出一個正整數N(≤1000),隨後N行,每行按下列格式給出一個人的房產:
編號 父 母 k 孩子1 … 孩子k 房產套數 總面積
其中編號是每個人獨有的一個4位數的編號;父和母分別是該編號對應的這個人的父母的編號(如果已經過世,則顯示-1);k(0≤k≤5)是該人的子女的個數;孩子i是其子女的編號。

輸出格式:
首先在第一行輸出家庭個數(所有有親屬關係的人都屬於同一個家庭)。隨後按下列格式輸出每個家庭的資訊:
家庭成員的最小編號 家庭人口數 人均房產套數 人均房產面積
其中人均值要求保留小數點後3位。家庭資訊首先按人均面積降序輸出,若有並列,則按成員編號的升序輸出。

輸入樣例:
10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100
輸出樣例:
3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

步驟

  1. 根據輸入輸出確定儲存結構,建立結構體、exist[]、father[] 陣列
  2. 寫好findFather(int n) 和 Union(int a, int b)兩個函式
int findFather(int n) {
	while(n != father[n])
		n = father[n];
	return n;
}
void Union(int a, int b) {
	int faA = findFather(a);
	int faB = findFather(b);
	if(faA > faB)
		father[faA] = faB;
	else
		father[faB] = faA;
}

  1. 寫好cmp函式
  2. 資料的讀入與合併
  3. 資料的整理
  4. 輸出結果

程式碼

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
struct input{
	int id, fid, mid, num, area;
	int cid[10];
}data[1000];
struct node{
    int id,people;
    double num,area;
    bool flag=false;
}ans[10000];
bool exist[10000];
int father[10000];
int findFather(int n) {
	while(n != father[n])
		n = father[n];
	return n;
}
void Union(int a, int b) {
	int faA = findFather(a);
	int faB = findFather(b);
	if(faA > faB)
		father[faA] = faB;
	else
		father[faB] = faA;
}
int cmp(node a, node b){
    if(a.area != b.area)
        return a.area > b.area;
    else
        return a.id < b.id;
}
int main(){
    int n, k, cnt = 0;
    scanf("%d",&n);
    for(int i = 0; i < 10000; i++)
        father[i] = i;
    
    //資料的輸入與合併
    for(int i = 0;i < n; i++){
        scanf("%d %d %d %d", &data[i].id, &data[i].fid, &data[i].mid, &k);
        exist[data[i].id] = true;
        if(data[i].fid! = -1){
            exist[data[i].fid] = true;
            Union(data[i].fid, data[i].id);
        }
        if(data[i].mid != -1){
            exist[data[i].mid] = true;
            Union(data[i].mid, data[i].id);
        }
        for(int j = 0; j < k; j++){
            scanf("%d", &data[i].cid[j]);
            exist[data[i].cid[j]] = true;
            Union(data[i].cid[j], data[i].id);
        }
        scanf("%d %d",&data[i].num, &data[i].area);
    }
    
    //資料的整理
    for(int i = 0; i < n; i++){
        int id = findFather(data[i].id);
        ans[id].id = id;
        ans[id].area += data[i].area;
        ans[id].num += data[i].num;
        ans[id].flag = true;
    }
    for(int i = 0; i < 10000; i++){
        if(exist[i])
            ans[findFather(i)].people++;
        if(ans[i].flag)
            cnt++;
    }
    for(int i = 0; i < 10000; i++){
        if(ans[i].flag){
            ans[i].num = (double)(ans[i].num * 1.0 / ans[i].people);
            ans[i].area = (double)(ans[i].area * 1.0 / ans[i].people);
        }
    }
     sort(ans, ans + 10000, cmp);
     
     //輸出結果
     printf("%d\n", cnt);
     for(int i = 0;i < cnt; i++)
        printf("%04d %d %.3f %.3f\n",ans[i].id,ans[i].people,ans[i].num,ans[i].area);
     return 0;

}

相關文章