1114 Family Property (25point(s))
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 个家庭成员,每个成员包含的信息:
- ID,父序号,母序号,孩子个数 K,k 个孩子序号,房子数目 M,房子总面积 Area
输出家庭个数,并输出每个家庭的信息:
- 成员最小序号,人口数,人均房产套数,人均房产面积
输出时,按人均面积降序,成员最小编号升序
设计思路:
并查集
- 读取数据时,就进行并查集的合并
- 遍历所有人,计算每个家庭的信息
- 把家庭信息排序,输出
编译器:C (gcc)
#include <stdio.h>
struct data {
int id, fid, mid;
};
struct node {
int id, num;
double sets, area;
};
int father[10010];
void makeset()
{
int i;
for (i = 0; i < 10010; i++)
father[i] = i;
}
int getfather(int v)
{
if (father[v] == v)
return v;
father[v] = getfather(father[v]);
return father[v];
}
void judge(int x, int y)
{
int fx = getfather(x);
int fy = getfather(y);
if (fx > fy)
father[fx] = fy;
else
father[fy] = fx;
}
int cmp(const void *a, const void *b)
{
struct node *p = *((struct node **)a), *q = *((struct node **)b);
double temp = p->area - q->area;
if (temp > 0)
return -1;
else if (temp < 0)
return 1;
return p->id - q->id;
}
int main(void)
{
int n;
int people[10010] = {0}, id, f, m, k, c;
double estate[10010][2] = {0};
struct node family[10010] = {0};
struct node *result[10010] = {0};
int i, cnt = 0;
makeset();
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d%d%d%d", &id, &f, &m, &k);
people[id] = 1;
if (f != -1) {
judge(id, f);
people[f] = 1;
}
if (m != -1) {
judge(id, m);
people[m] = 1;
}
while (k > 0) {
scanf("%d", &c);
judge(id, c);
people[c] = 1;
k--;
}
scanf("%lf%lf", &estate[id][0], &estate[id][1]);
}
for (i = 0; i < 10010; i++) {
if (people[i]) {
int temp = getfather(i);
family[temp].num++;
family[temp].sets += estate[i][0];
family[temp].area += estate[i][1];
if (temp == i) {
family[temp].id = temp;
result[cnt++] = &family[temp];
}
}
}
for (i = 0; i < cnt; i++) {
result[i]->sets /= result[i]->num;
result[i]->area /= result[i]->num;
}
qsort(result, cnt, sizeof(result[0]), cmp);
printf("%d\n", cnt);
for (i = 0; i < cnt; i++)
printf("%04d %d %.3lf %.3lf\n", result[i]->id, result[i]->num, result[i]->sets, result[i]->area);
return 0;
}