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 (≤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
题目大意:输入N个家族的成员、房产数量和面积,输出每个大家族中编号最小的人,家族成员数量,家族房产平均数量。
题解1:
思路:并查集。
对每个家族,输入的时候选择编号最小的人作为父亲,进行合并。
每个家族的第一个人,把房产数量和面积记到他的名下。
所有的家族输入后,更新所有人的父亲(保证每个人都找到了真正的父节点)。
遍历,找到每个家族的最小编号,把所有房产改到他的名下,并记录总家族数。
排序,输出。
注意事项:
1.比较的时候,由于每个人所记的家族成员数量、房产信息不一样(非父节点不记录家族成员数量),如果初始化成员数量,房产数量和面积都为0,会导致比较出错。修改:初始化成员数量为1(即他自己)(后面统计成员数量的时候注意不要重复加上父节点自己),初始化房产数量和面积都为0,用乘法代替除法进行房产面积平均值比较。
2.每个人的编号是一个4位数字,包括0000。
3.初始化book=-1,用来区分该编号的成员是否存在。
4.使用vector记录成员信息应该可以减少很多内存,不过这里用数组通过了,就暂时没有尝试vector。
源代码1:
#include<iostream>
#include<algorithm>
#include<map>
#include<stdlib.h>
#include<vector>
using namespace std;
struct node
{
int id=10000, book = -1, cnt = 1, num = 0, area = 0;
};
bool cmp(node a, node b)
{
if (a.area * b.cnt != b.area * a.cnt)return a.area * b.cnt > b.area * a.cnt;
else return a.id < b.id;
}
node person[10001];
int getfather(int x)
{
if (x == person[x].book)return x;
else return person[x].book = getfather(person[x].book);
}
void merge(int x, int y)
{
int fx, fy;
fx = getfather(x);
fy = getfather(y);
if(fx<fy)person[fy].book = fx;
else person[fx].book = fy;
return;
}
int main()
{
int n, k, htemp, ftemp, i, j,mmax=0;
map<int, int>mmap;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
int self, others;
scanf("%d", &self);
if(person[self].book ==-1)person[self].book=person[self].id= self;
for (j = 0; j < 2; j++)
{
scanf("%d", &others);
if (others != -1)
{
if (person[others].book == -1)person[others].book = person[others].id = others;
merge(self, others);
}
}
scanf("%d", &k);
for (j = 0; j < k; j++)
{
scanf("%d", &others);
if (person[others].book == -1)person[others].book = person[others].id = others;
merge(self,others);
}
scanf("%d %d", &person[self].num, &person[self].area);
}
for (i = 0; i <= 10000; i++)
if(person[i].book!=-1)getfather(i);
mmax = 0;
for (i = 0; i < 10001; i++)
{
if (person[i].book != -1)
{
if (person[i].book == i)mmax++;
else
{
person[person[i].book].num += person[i].num;
person[i].num = 0;
person[person[i].book].area += person[i].area;
person[i].area = 0;
person[person[i].book].cnt++;
}
}
}
sort(person, person+10001, cmp);
printf("%d\n", mmax);
for (i = 0; i < mmax; i++)
printf("%04d %d %.3lf %.3lf\n", person[i].id, person[i].cnt, 1.0*person[i].num/person[i].cnt, 1.0*person[i].area/person[i].cnt);
system("pause");
return 0;
}