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 M_estate 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;M_estate 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 AVG_sets AVG_area
where ID is the smallest ID in the family; M is the total number of family members; AVG_sets is the average number of sets of their real estate; and AVG_area 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 100Sample Output:
3 8888 1 1.000 1000.000 0001 15 0.600 100.000 5551 4 0.750 100.000
思路分析:考查并查集,这道题很烦。
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAX 10001
// 这里有个BUG,我把MAX写成10000的时候,9999的父节点就变成6663了
// 正常情况应该是9999,还不知道为啥
using namespace std;
typedef struct {
int house;
int area;
} Person;
typedef struct { // 保存最后的结果数组,最后要进行排序
int minPerson; // 家族最小成员的编号
int sumPerson; // 家族所有人的数量
int sumHouse; // 家族一共有的房产数量
int sumArea; // 家族一共有的房产面积
double aveHouse; // 房产数量人均值
double aveArea; // 房产面积人均值
} Result;
Person p[MAX]; // 每个人的房产信息
int isRoot[MAX]; // 是否是根节点
int Father[MAX]; // 并查集数组
int visit[MAX]; // 结点是否访问过
void initPerson() {
for( int i = 0; i < MAX; i++ ) {
Father[i] = i;
visit[i] = 0;
isRoot[i] = 0;
p[i].house = 0;
p[i].area = 0;
}
}
int findFather( int x ) {
int a = x;
while( x != Father[x] ) {
x = Father[x];
}
// 路径压缩
int z;
while( a != Father[a] ) {
z = a;
a = Father[a];
Father[z] = x;
}
return x;
}
void Union( int a, int b ) {
int findA = findFather( a );
int findB = findFather( b );
if( findA != findB ) {
Father[findA] = findB;
}
//printf( "%04d and %04d in set\n", a, b );
}
int cmp( Result a, Result b ) {
if( a.aveArea != b.aveArea ) {
return a.aveArea > b.aveArea ? 1 : 0;
}
return a.minPerson > b.minPerson ? 0 : 1;
}
int main() {
//freopen( "123.txt", "r", stdin );
int n;
int id, father, mother, k, child, house, area;
scanf( "%d", &n );
initPerson();
for( int i = 0; i < n; i++ ) {
scanf( "%d%d%d%d", &id, &father, &mother, &k );
visit[id] = visit[father] = visit[mother] = 1;
if( father != -1 )
Union( id, father );
if( mother != -1 )
Union( id, mother );
while( k-- ) {
scanf( "%d", &child );
visit[child] = 1;
Union( id, child );
}
scanf( "%d%d", &p[id].house, &p[id].area );
}
for( int i = 0; i < MAX; i++ ) {
if( visit[i] ) {
int fa = findFather( i );
//printf( "%04d's father = %04d\n", i, fa );
isRoot[fa] = 1;
}
}
//printf( "\n" );
vector<int> vec;
for( int i = 0; i < MAX; i++ ) {
if( isRoot[i] ) {
//printf( "%d\n", i );
vec.push_back( i );
}
}
vector<Result> vecR;
for( int i = 0; i < vec.size(); i++ ) {
int fa = vec[i];
bool flag = false;
int min;
int sumPerson = 0;
int sumArea = 0;
int sumHouse = 0;
for( int i = 0; i < MAX; i++ ) {
if( fa == findFather( i ) ) {
if( !flag ) {
min = i;
flag = true;
}
sumPerson++;
sumHouse += p[i].house;
sumArea += p[i].area;
}
}
Result r;
r.minPerson = min;
r.sumPerson = sumPerson;
r.sumHouse = sumHouse;
r.sumArea = sumArea;
r.aveHouse = (double)sumHouse / (double)sumPerson;
r.aveArea = (double)sumArea / (double)sumPerson;
vecR.push_back( r );
}
sort( vecR.begin(), vecR.end(), cmp );
printf( "%d\n", vecR.size() );
for( int i = 0; i < vecR.size(); i++ ) {
printf( "%04d %d %.3lf %.3lf\n",
vecR[i].minPerson, vecR[i].sumPerson, vecR[i].aveHouse, vecR[i].aveArea );
}
return 0;
}