zoukankan      html  css  js  c++  java
  • A1114. Family Property

    This time, you are supposed to help us collect the data for family-owned property. Given each person's family members, and the estate(房产)info under his/her own name, we need to know the size of each family, and the average area and number of sets of their real estate.

    Input Specification:

    Each input file contains one test case. For each case, the first line gives a positive integer N (<=1000). Then N lines follow, each gives the infomation of a person who owns estate in the format:

    ID Father Mother k Child1 ... Childk M_estate Area

    where ID is a unique 4-digit identification number for each person; Father and Mother are the ID's of this person's parents (if a parent has passed away, -1 will be given instead); k (0<=k<=5) is the number of children of this person; Childi's are the ID's of his/her children; M_estate is the total number of sets of the real estate under his/her name; and Area is the total area of his/her estate.

    Output Specification:

    For each case, first print in a line the number of families (all the people that are related directly or indirectly are considered in the same family). Then output the family info in the format:

    ID M AVG_sets AVG_area

    where ID is the smallest ID in the family; M is the total number of family members; AVG_sets is the average number of sets of their real estate; and AVG_area is the average area. The average numbers must be accurate up to 3 decimal places. The families must be given in descending order of their average areas, and in ascending order of the ID's if there is a tie.

    Sample Input:

    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
    

    Sample Output:

    3
    8888 1 1.000 1000.000
    0001 15 0.600 100.000
    5551 4 0.750 100.000

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string>
     5 #include<vector>
     6 using namespace std;
     7 double estate[10000], area[10000];
     8 int father[10000], familyNum[10000], tb[10000];
     9 bool cmp(int a, int b){
    10     if(area[a] != area[b])
    11         return area[a] > area[b];
    12     else return a < b;
    13 }
    14 int findFather(int x){
    15     int temp = x;
    16     while(x != father[x]){
    17         x = father[x];
    18     }
    19     int temp2;
    20     while(temp != x){
    21         temp2 = father[temp];
    22         father[temp] = x;
    23         temp = temp2;
    24     }
    25     return x;
    26 }
    27 void merge(int a, int b){
    28     if(a == -1 || b == -1)
    29         return;
    30     int af = findFather(a);
    31     int bf = findFather(b);
    32     if(af == bf)
    33         return;
    34     if(af > bf)
    35         swap(af, bf);
    36     father[bf] = af;
    37 }
    38 int main(){
    39     int N;
    40     scanf("%d", &N);
    41     int id, idf, idm, child;
    42     int chiN;
    43     for(int i = 0; i < 10000; i++){
    44         estate[i] = 0;
    45         area[i] = 0;
    46         father[i] = i;
    47         familyNum[i] = 0;
    48         tb[i] = 0;
    49     }
    50     for(int i = 0; i < N; i++){
    51         cin >> id >> idf >> idm >> chiN;
    52         tb[id] = tb[idf] = tb[idm] = 1;
    53         merge(id, idf);
    54         merge(id, idm);
    55         int son;
    56         for(int j = 0; j < chiN; j++){
    57             cin >> son;
    58             tb[son] = 1;
    59             merge(id, son);
    60         }
    61         cin >> estate[id] >> area[id];
    62     }
    63     int cnt = 0;
    64     vector<int> ans;
    65     for(int i = 0; i < 10000; i++){
    66         if(tb[i] == 1){
    67             int ff = findFather(i);
    68             if(ff != i){
    69                 estate[ff] += estate[i];
    70                 area[ff] += area[i];
    71             }
    72             familyNum[ff]++;
    73             if(i == ff){
    74                 cnt++;
    75                 ans.push_back(i);
    76             }
    77             
    78         }
    79     }
    80     for(int i = 0; i < 10000; i++){
    81         if(tb[i] == 1 && father[i] == i){
    82             int Num = familyNum[i];
    83             area[i] = area[i] / (double)Num;
    84             estate[i] = estate[i] / (double)Num;
    85         }
    86     }
    87     sort(ans.begin(), ans.end(), cmp);
    88     printf("%d
    ", cnt);
    89     for(int i = 0; i < ans.size(); i++){
    90         printf("%04d %d %.3f %.3f
    ", ans[i], familyNum[ans[i]], estate[ans[i]], area[ans[i]]);
    91     }
    92     cin >> N;
    93     return 0;
    94 }
    View Code

    总结:

    1、由于一个人既有双亲又有N多个孩子,所以用树形结构肯定不行。只能用并查集或者图搜索。

    2、并查集:并查集仅仅对父母、子女的关系进行合并处理。房子数、面技数、家庭人口等先不计算,仅仅存在每个人各自的对应数组中。由于序号不是连续的1到N,因此father数组中会有很多无效节点,需要一个tb数组在输入的时候就记录哪些是有效的节点。 在并查集处理完家庭关系之后,对father数组再次遍历,当遇到非根节点时,查找到他对应的根节点,并把房子、面积、等累加至根节点对应的数组中。  

    3、由于要求输出的id为家族中最小id,所以在两个root合并时,要将更小的root作为新的root。

  • 相关阅读:
    Nginx 启动错误 Failed to read PID from /run/nginx.pid
    CentOS7 下 nginx 无法加载 Django 静态文件的问题
    SSD + 机械硬盘装 CentOS 分区的问题
    CentOS7 单机维护模式
    编译安装 redis 6.2.1
    谷歌师兄刷题笔记
    我用 DCL 写出了单例模式,结果阿里面试官不满意!
    红黑树杀人事件始末
    头条二面:详述一条 SQL 的执行流程
    jvisual远程 springBoot项目
  • 原文地址:https://www.cnblogs.com/zhuqiwei-blog/p/8576568.html
Copyright © 2011-2022 走看看