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 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≤k≤5) 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
题目大意:找出每个家庭的根,家庭人数,人均房产套数,人均房产面积。输出时优先人均面积降序,然后根成员编号升序排序。
分析:典型的并查集应用。
1) 合并的时候选取编号小的作为根,-1的时候表示单亲不存在,不用进行合并。
2) 录入房产套数的时候用float,后面输出人均房产套数就不用类型转换了。
3) 遍历集合,统计有效信息,排序输出。
完整代码:
#include<bits/stdc++.h>
using namespace std;
vector<int> father(10010),cnt(10010,1),ans;
vector<double>area(10010),estate(10010);
bool vis[10010];
set<int>s;
bool cmp(int a,int b){
return area[a]!=area[b]?area[a]>area[b]:a<b;
}
int find(int x){
int a=x;
while(x!=father[x]){
x=father[x];
}
while(a!=father[a]){
int z=a;
a=father[a];
father[z]=x;
}
return x;
}
void Union(int x,int y){
if(y==-1) return ;
vis[y]=true;
int fx=find(x);
int fy=find(y);
if(fx>fy) swap(fx,fy);
father[fy]=fx;
}
int main(){
//freopen( "123.txt", "r", stdin );
int n,id,fid,mid,k,child;
cin>>n;
for(int i=0;i<10010;i++) father[i]=i;
for(int i=0;i<n;i++){
cin>>id>>fid>>mid>>k;
vis[id]=true;
Union(id,fid);
Union(id,mid);
for(int j=0;j<k;j++){
cin>>child;
Union(id,child);
}
cin>>estate[id]>>area[id];
}
for(int i=0;i<10010;i++){
if(!vis[i]) continue; //没录入i信息
int fa=find(i);
if(s.find(fa)==s.end()){
ans.push_back(fa);
s.insert(fa);
}
if(fa!=i){ //根不能重复 +,根初始化为1
cnt[fa]++;
estate[fa]+=estate[i];
area[fa]+=area[i];
}
}
for(int i=0;i<ans.size();i++){
area[ans[i]]= (1.0*area[ans[i]])/cnt[ans[i]];
estate[ans[i]]= (1.0*estate[ans[i]])/cnt[ans[i]];
}
sort(ans.begin(),ans.end(),cmp);
cout<<ans.size();
for(int i=0;i<ans.size();i++)
printf("\n%04d %d %.3f %.3f",ans[i],cnt[ans[i]],estate[ans[i]],area[ans[i]]);
return 0;
}
That’s all !