题目粗心
给定一个人的家庭成员及其房产信息,须要晓得每一个家庭的人数,均匀占地面积和房产数目。
算法思路
这是一道惯例的并查集利用题目,咱们首先应用families数组保留所有的输出集,并在输出的时候记录哪些是输出的成员(应用visited记录),并且合并那些是一家人的成员,这样就将所有成员都进行了归类在各自的家庭,而后计算每一个家庭的占地总面积和总房产数目,并且应用flag标记以后家庭(在[0,10000]中有意义的家庭),而后在[0,10000]的所有人中统计所有的家庭成员数目(visited[i]=true的就是)和家庭数目(flag为true的人代表一个家庭),最初计算房子的均匀面积和数目。
留神点
- 1、在输出的时候families的下标是从0开始到n-1完结,这样不便遍历输出的成员并进行信息计算
- 2、计算房子的均匀面积和数目的时候,得应用总共的信息total_*除以家庭人数,因为该计算过程会执行屡次。
提交后果
AC代码
#include<cstdio>#include<algorithm>#include<vector>using namespace std;struct Family { int ID; int father; int mother; vector<int> children; int estate; int area;} families[1001];// 存储后果集struct Node { int ID; int total_number; double Avg_sets; double Avg_area; int total_sets; int total_area; bool flag;// 标记以后家庭} nodes[10000];bool cmp(const Node &a, const Node &b) { return a.Avg_area != b.Avg_area ? a.Avg_area > b.Avg_area : a.ID < b.ID;}// 统计在[0,10000]中哪些是存在的成员bool visited[10000];// 记录每一个人的先人(可能不在输出中)int father[10000];// 找到x的先人,这里采纳了压缩门路的形式int findFather(int x) { int a = x; while (x != father[x]) { x = father[x]; } while (a != father[a]) { int z = father[a]; father[a] = x; a = z; } return x;}void Union(int a, int b) { int fa = findFather(a); int fb = findFather(b); if (fa < fb) { father[fb] = fa; } else { father[fa] = fb; }}int main() { for (int i = 0; i < 10000; ++i) { father[i] = i; } int n; scanf("%d", &n); Family member; int k; for (int i = 0; i < n; ++i) { scanf("%d %d %d %d", &member.ID, &member.father, &member.mother, &k); int child; for (int j = 0; j < k; ++j) { scanf("%d", &child); member.children.push_back(child); visited[child] = true; Union(member.ID, child); } scanf("%d %d", &member.estate, &member.area); families[i] = member; visited[member.ID] = true; if (member.father != -1) { visited[member.father] = true; Union(member.ID, member.father); } if (member.mother != -1) { visited[member.mother] = true; Union(member.ID, member.mother); } } // 将所有归类的家庭进行计算相干信息 for (int i = 0; i < n; ++i) { int id = findFather(families[i].ID); nodes[id].ID = id; nodes[id].total_area += families[i].area; nodes[id].total_sets += families[i].estate; nodes[id].flag = true; } int num = 0; // 统计家庭成员人数和家庭数目 for (int i = 0; i < 10000; ++i) { if (visited[i]) { int id = findFather(i); ++nodes[id].total_number; } if (nodes[i].flag) { ++num; } } // 计算房子的均匀面积和均匀数目 for (int i = 0; i < 10000; ++i) { if (visited[i]) { int id = findFather(i); nodes[id].Avg_area = nodes[id].total_area*1.0/nodes[id].total_number; nodes[id].Avg_sets = nodes[id].total_sets*1.0/nodes[id].total_number; } } printf("%d\n", num); sort(nodes,nodes+10000,cmp); for(int i=0;i<num;++i){ printf("%04d %d %.3f %.3f\n",nodes[i].ID,nodes[i].total_number,nodes[i].Avg_sets,nodes[i].Avg_area); } return 0;}