• PAT甲级——1114 Family Property (并查集)



    此文章同步发布在我的CSDN上https://blog.csdn.net/weixin_44385565/article/details/89930332

    1114 Family Property (25 分)

    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 (≤). Then N lines follow, each gives the infomation of a person who owns estate in the format:

    ID Father Mother Child1​​Childk​​ Mestate​​ 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) is the number of children of this person; Childi​​'s are the ID's of his/her children; Mestate​​ 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 AVGsets​​ AVGarea​​

    where ID is the smallest ID in the family; M is the total number of family members; AVGsets​​ is the average number of sets of their real estate; and AVGarea​​ 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

    题目大意:根据给出的数据分类出各个家庭,然后输出家庭个数;接下来输出每个家庭的成员ID(只需输出家庭成员中最小的ID)、成员数量、平均房产数量、平均房产面积,输出顺序为平均房产面积降序、ID升序。

    思路:用并查集S给家庭分类,为了方便找出最小的家庭成员ID,对并查集的操作稍作修改,集合元素初始化为对应的下标,若S[X]==X,则X为根,unionSet()函数将大根集合并到小根集合里;家庭成员计数时需要对已经访问过的ID进行标记,防止重复计数,用visit数组标记每个ID。

    总结:其实我是比较害怕这类问题的,看起来简单,可是信息一多思考起来就容易混乱,需要很细心很耐心地分析,用不到什么算法知识却超级消耗时间~

      1 #include <iostream>
      2 #include <vector>
      3 #include <unordered_map>
      4 #include <algorithm>
      5 using namespace std;
      6 struct node1 {
      7     int ID, fID, mID, k, Me, area;
      8     vector <int> child;
      9 };
     10 struct node2 {
     11     int sumM = 0, sumSets = 0, sumArea = 0;
     12 };
     13 struct node3 {
     14     int ID, M;
     15     float AVGs, AVGa;
     16 };
     17 vector <int> S(10000);
     18 vector <bool> visit(10000, false);
     19 void initialize();//对集合S进行初始化
     20 bool cmp(node3 &a, node3 &b);//排序规则
     21 int getNum(node1 &a);//获取家庭成员的数量
     22 int find(int X);
     23 void unionSet(int X, int Y);
     24 int main()
     25 {
     26     int N;
     27     scanf("%d", &N);
     28     vector <node1> data(N);
     29     unordered_map <int, node2> mp;
     30     initialize();
     31     for (int i = 0; i < N; i++) {
     32         node1 tmp;
     33         scanf("%d%d%d%d", &tmp.ID, &tmp.fID, &tmp.mID, &tmp.k);
     34         if (tmp.fID != -1)
     35             unionSet(tmp.ID, tmp.fID);
     36         if (tmp.mID != -1)
     37             unionSet(tmp.ID, tmp.mID);
     38         if (tmp.k != 0) {
     39             for (int j = 0; j < tmp.k; j++) {
     40                 int cID;
     41                 scanf("%d", &cID);
     42                 tmp.child.push_back(cID);
     43                 unionSet(tmp.ID, cID);
     44             }
     45         }
     46         scanf("%d%d", &tmp.Me, &tmp.area);
     47         data[i] = tmp;
     48     }
     49     for (int i = 0; i < N; i++) {
     50         int ID = find(data[i].ID);
     51         mp[ID].sumM += getNum(data[i]);
     52         mp[ID].sumSets += data[i].Me;
     53         mp[ID].sumArea += data[i].area;
     54     }
     55     vector <node3> ans;
     56     for (auto it = mp.begin(); it != mp.end(); it++) {
     57         int ID = it->first,
     58             M = it->second.sumM;
     59         float AVGs = it->second.sumSets*1.0 / M,
     60             AVGa = it->second.sumArea*1.0 / M;
     61         ans.push_back({ ID,M,AVGs,AVGa });
     62     }
     63     sort(ans.begin(), ans.end(), cmp);
     64     printf("%d
    ", ans.size());
     65     for (int i = 0; i < ans.size(); i++)
     66         printf("%04d %d %.3f %.3f
    ", ans[i].ID, ans[i].M, ans[i].AVGs, ans[i].AVGa);
     67     return 0;
     68 }
     69 int getNum(node1 &a) {
     70     int n = 0;
     71     if (!visit[a.ID]) {
     72         n++;
     73         visit[a.ID] = true;
     74     }
     75     if ((a.fID != -1 )&& (!visit[a.fID])) {
     76         n++;
     77         visit[a.fID] = true;
     78     }
     79     if ((a.mID != -1) && (!visit[a.mID])) {
     80         n++;
     81         visit[a.mID] = true;
     82     }
     83     if (a.k != 0) {
     84         for (int i = 0; i < a.k; i++) {
     85             if (!visit[a.child[i]]) {
     86                 n++;
     87                 visit[a.child[i]] = true;
     88             }
     89         }
     90     }
     91     return n;
     92 }
     93 void unionSet(int X, int Y) {
     94     int rootX = find(X),
     95         rootY = find(Y);
     96     if (rootX > rootY)
     97         S[rootX] = S[rootY];
     98     else 
     99         S[rootY] = S[rootX];
    100 }
    101 int find(int X) {
    102     if (S[X] == X) {
    103         return X;
    104     }
    105     else {
    106         return S[X] = find(S[X]);//递归地压缩路径
    107     }
    108 }
    109 void initialize() {
    110     for (int i = 0; i < 10000; i++) 
    111         S[i] = i;//将集合元素初始化为对应的下标,每个集合的根节点就是当前家庭的最小ID
    112 }
    113 bool cmp(node3 &a, node3 &b) {
    114     if (a.AVGa != b.AVGa) 
    115         return a.AVGa > b.AVGa;
    116     else 
    117         return a.ID < b.ID;
    118 }
     
  • 相关阅读:
    登陆跳转回原来页面
    magento获取当前浏览器的url和对url判断处理
    Magento获取购物车所有信息
    magento查询商品库存
    金额转换成0.00的形式
    Magento网站运行原理解析
    linux下如何禁用root账户直接登陆
    web前端常用的10个jQuery特效总结
    js函数
    网站css
  • 原文地址:https://www.cnblogs.com/yinhao-ing/p/10828472.html
Copyright © 2020-2023  润新知