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 child2 ... childk M 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; Child**i'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 AVG_{sets} AVG_{area}\)

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.先将录入的数据按照输入的形式存在数组中,录入的同时完成集合的合并,然后再从录入的数据中挑出需要的数据,最后对挑出的数据仓晒礼输出;

2.在录入的同时进行集合的合并,并将数据按照输出的格式存储,然后进行处理

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<unordered_map>
#include<set>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int nmax = 10100;
int fath[nmax];
void init(){
for(int i = 0; i < nmax; ++i)fath[i] = i;
}
int findF(int x){
int z = x;
while(x != fath[x])x = fath[x];
while(z != fath[z]){
int temp = fath[z];
fath[z] = x;
z = temp;
}
return x;
}
void Union(int a, int b){
int fa = findF(a), fb = findF(b);
if(fa < fb)fath[fb] = fa;
else if(fa > fb)fath[fa] = fb;
}
struct node{
int id, people;
double num, area;
bool flag = false;
bool operator < (node &a)const{
return area != a.area ? area > a.area : id < a.id;
}
}ans[nmax];
struct data{
int id, fid, mid, k;
int child[6];
int num, area;
}v[nmax];
bool vis[nmax] = {false};
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
init();
int N;
scanf("%d", &N);
//录入数据并合并,由于序号不连续,要标记哪些序号已经出现过
for(int i = 0; i < N; ++i){
int id, fid, mid, k;
scanf("%d%d%d%d", &id, &fid, &mid, &k);
v[id].id = id;
v[id].fid = fid;
v[id].mid = mid;
v[id].k = k;
vis[id] = true;
if(fid != -1){
Union(id, fid);
vis[fid] = true;
}
if(mid != -1){
Union(id, mid);
vis[mid] = true;
}
for(int j = 0; j < k; ++j){
scanf("%d", &v[id].child[j]);
Union(id, v[id].child[j]);
vis[v[id].child[j]] = true;
}
scanf("%d%d", &v[id].num, &v[id].area);
}
//统计并抽出需要的数据,用flag标记该根节点是否已经出现
int cnt = 0;
for(int i = 0; i < nmax; ++i){
if(vis[i] == true){
int index = findF(i);
ans[index].id = index;
ans[index].people++;
ans[index].num += v[i].num;
ans[index].area += v[i].area;
if(ans[index].flag == false)cnt++;
ans[index].flag = true;
}
}
//处理
for(int i = 0; i < nmax; ++i){
if(ans[i].flag == true){
ans[i].num /= ans[i].people;
ans[i].area /= ans[i].people;
}
}
//排序输出
sort(ans, ans + nmax);
printf("%d\n", cnt);
for(int i = 0; i < cnt; ++i){
printf("%04d %d %.3f %.3f\n", ans[i].id, ans[i].people, ans[i].num, ans[i].area);
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int Nmax = 10000;
int father[Nmax];
bool vis[Nmax] = {false};
struct node{
int id, peoNum;
double Sav, Aav;
};
void init(){
for(int i = 0; i < Nmax; ++i)father[i] = i;
}
int findF(int x){
int z = x;
while(x != father[x])x = father[x];
while(z != father[z]){
int temp = father[z];
father[z] = x;
z = temp;
}
return x;
}
void Union(int a, int b){
int fa = findF(a), fb = findF(b);
if(fa != fb)father[fb] = fa;
}
bool cmp(node a, node b){
bool flag = false;
if(a.Aav / a.peoNum > b.Aav / b.peoNum){
flag = true;
}else if(a.Aav / a.peoNum == b.Aav / b.peoNum && a.id < b.id){
flag = true;
}
return flag;
}
int main(){
init();
int N = 0;
vector<node>v, v2;
scanf("%d", &N);
for(int i = 0; i < N; ++i){
int f, m, id, k, idm = 10000;
int peonum = 0;
scanf("%d%d%d%d", &id, &f, &m, &k);
if(f == -1 && m == -1)idm = id;
if(f == -1 && m != -1)idm = min(id, m);
if(f != -1 && m == -1)idm = min(id, f);
if(f != -1 && m != -1)idm = min(min(m, f), id);
if(!vis[id]){
peonum = 1;
vis[id] = true;
}
if(f != -1){
Union(f, id);
if(!vis[f]){
peonum++;
vis[f] = true;
}
}
if(m != -1){
Union(m, id);
if(!vis[m]){
peonum++;
vis[m] = true;
} }
for(int j = 0; j < k; ++j){
int child;
scanf("%d", &child);
idm = min(idm, child);
Union(id, child);
if(!vis[child]){
peonum++;
vis[child] = true;
}
}
int setNum, area;
scanf("%d%d", &setNum, &area);
int flag = false;
for(int j = 0; j < v.size(); ++j){
if(findF(v[j].id) == findF(idm)){
v[j].id = min(idm, v[j].id);
v[j].peoNum += peonum;
v[j].Sav += (double)setNum;
v[j].Aav += (double)area;
flag = true;
break;
}
}
if(!flag)v.push_back({idm, peonum , (double)setNum, (double)area});
}
//录入数据的时候只合并了一部分家庭,再合并一遍
v2.push_back(v[0]);
for(int i = 1; i < v.size(); ++i){
int flag = false;
for(int j = 0; j < v2.size(); ++j){
if(findF(v[i].id) == findF(v2[j].id)){
v2[j].id = min(v[i].id, v2[j].id);
v2[j].peoNum += v[i].peoNum;
v2[j].Sav += v[i].Sav;
v2[j].Aav += v[i].Aav;
flag = true;
break;
}
}
if(!flag)v2.push_back(v[i]);
}
cout<<v2.size()<<endl;
sort(v2.begin(), v2.end(), cmp);
for(int i = 0; i < v2.size(); ++i){
printf("%04d %d %.3f %.3f\n", v2[i].id, v2[i].peoNum, v2[i].Sav / v2[i].peoNum, v2[i].Aav / v2[i].peoNum);
}
return 0;
}

最新文章

  1. Requests库练习
  2. 长文丨papi、咪蒙、罗胖之后,内容创业的机会在哪儿
  3. ZT 螨虫知识2
  4. yum仅下载RPM包不安装
  5. android小知识之自定义通知(toast)
  6. .NET中IDisposable接口的基本使用
  7. python捕获异常及方法总结
  8. abstract关键字 super 关键字 类与继承
  9. 玩转Kafka的生产者——分区器与多线程
  10. 涂鸦之作WanAndroid第三方APP
  11. JS 浅谈函数柯里化,不明觉厉
  12. php api 接口
  13. 【gulp-sass】本地搭建sass开发环境
  14. noip2017d1t3
  15. 使用pt-table-checksum校验MySQL主从复制【转】
  16. Oracle 声明常量 (转)
  17. gridview获取选中行索引及当前行数据
  18. MySQL中的表级锁
  19. django之管理静态文件
  20. ASP.NET Core获取微信订单数据

热门文章

  1. 阿里云ilogtail收集自建Kubernetes容器日志文件
  2. makefile 规则与原理
  3. Spring支持的常用数据库传播属性和事务隔离级别
  4. GoLang设计模式18 - 适配器模式
  5. 【LeetCode】760. Find Anagram Mappings 解题报告
  6. 【LeetCode】836. Rectangle Overlap 解题报告(Python)
  7. 【LeetCode】821. Shortest Distance to a Character 解题报告(Python)
  8. 破解C#反编译软件Reflector 11.1.0.2167(最新版)(附补丁下载)
  9. Codeforces 189A:Cut Ribbon(完全背包,DP)
  10. On the Optimization of Deep Networks: Implicit Acceleration by Overparameterization