Topic restatement
Given each person's family members and the real estate under their own name, please count the population of each family, the per capita real estate area and the number of real estate units.
Input format:
Enter the first line to give a positive integer n (< 1000), followed by N lines, each line giving a person's property in the following format:
Number parent k child 1 Children k total area of real estate units
Among them, the number is a 4-digit number unique to each person; the parent and parent are the number of the parent of the person corresponding to the number (if they have passed away, display - 1); k (0 ≤ k ≤ 5) is the number of children of the person; child i is the number of children.
Output format:
First, output the number of families in the first line (all related people belong to the same family). Then output information for each family in the following format:
Minimum number of family members number of family population number of real estate units per capita area of real estate per capita
The per capita value shall be 3 decimal places. Family information is first output in descending order of per capita area, and if there is parallel, it is output in ascending order of member number.
Input example:
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
Output example:
3 8888 1 1.000 1000.000 0001 15 0.600 100.000 5551 4 0.750 100.000
Title Solution
Using concurrent query set, put all members of a family into a set, and finally find the relevant information of the set.
If you don't know and check the collection, this blog post is good: Union checking set
This article refers to the ideas [patl2-007] family property
There are detailed comments in the code, hope to help you
C++ AC
#include <iostream> #include <bits/stdc++.h> #define MAX 10010 using namespace std; struct person//Structure used to save input samples { int id;//number int f_id;//Father's number int m_id;//Mother's number int k;//Number of children int child[10];//Save child's array int house_num;//House number int sum_area;//total area }; struct rs//Structure used to output results -- family collection { int id;//Minimum number int person_num;//Family size double ave_house;//Average number of properties double ave_area;//Average real estate area }; int p[MAX];//Used to save superior bool vis[MAX];//It is used to save the number. Because we use the method of typing table, we need to see which number is valid bool cmp(rs x,rs y)//Custom structure comparison { if(x.ave_area==y.ave_area) { return x.id<y.id; } else { return x.ave_area>y.ave_area; } } int find1(int x)//And look for the top leaders { if(x==p[x]) { return x; } else { return p[x]=find1(p[x]); } } void unite(int x,int y)//Consolidation of consolidation { x=find1(x); y=find1(y); if(x==y) return; else { p[x]=y; } } int main() { ios::sync_with_stdio(false); memset(vis,0,sizeof(vis)); person ps[10005];//Use to save input samples rs result[10005];//Use to save output samples for(int i=0; i<10005; i++) { p[i]=i;//Default your superior is yourself } int n; cin>>n; for(int i=0; i<n; i++) { cin>>ps[i].id>>ps[i].f_id>>ps[i].m_id>>ps[i].k; vis[ps[i].id]=true;//Set the number to be valid if(ps[i].f_id!=-1) { unite(ps[i].id,ps[i].f_id);//Merge number and father's number vis[ps[i].f_id]=true;//Setting the number of the father is also valid } if(ps[i].m_id!=-1) { unite(ps[i].id,ps[i].m_id);//Mother's number vis[ps[i].m_id]=true;//Setting the number of the father is also valid } for(int j=0; j<ps[i].k; j++) { cin>>ps[i].child[j]; unite(ps[i].id,ps[i].child[j]);//Put all the children's numbers in this collection vis[ps[i].child[j]]=true;//The child's number is also valid } cin>>ps[i].house_num>>ps[i].sum_area; } for(int i=0; i<n; i++) { int id=find1(ps[i].id);//Looking for the top result[id].ave_house+=ps[i].house_num;//The number of property units with the current number added to the top level result[id].ave_area+=ps[i].sum_area;//Total area of the highest level plus the current number } //It's used to record whether it's the superior or not bool record[100010]; memset(record,0,sizeof(record)); int k=0; for(int i=0; i<=9999; i++) { if(vis[i]) { int t=find1(i); record[t]=true; if(!result[t].person_num)//Ensure that the id in the output result is the minimum id in the family { result[t].id=i; } result[t].person_num++; } } for(int i=0; i<10010; i++) { if(record[i]) { result[i].ave_area=result[i].ave_area*1.0/result[i].person_num; result[i].ave_house= result[i].ave_house*1.0/result[i].person_num; } } //Sort the structure sort(result,result+10000,cmp); int ans=0; for(int i=0; i<10000; i++) { if(result[i].person_num) { ans++; } } printf("%d\n",ans); for(int i=0; i<ans; i++) { if(result[i].person_num) { printf("%04d %d %.3f %.3f\n",result[i].id,result[i].person_num,result[i].ave_house,result[i].ave_area); } } return 0; }