题目分析:
题目给出数据为:人编号(4位),人房子信息,人与人的关系(有关系就是一个家庭的)。
所求:家庭数目、家庭信息(先求出成员数、房子总数、房子总面积即可)
抽象分析:给定一堆点,点与点的连通关系,求有几个连通区域,此连通区域信息
所用算法:并查集
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<cstdio>
#define iIN(x,y) for(int i=x;i<y;i++)
#define jIN(x,y) for(int j=x;j<y;j++)
using namespace std;
vector<int> house;//房子数量
vector<int> S; //房子面积
vector<int> people;//个人信息
int root[10000]; //root[x]里面存的是x的根
int mark[10000];
//a1 a2 a3 a4存家庭信息
vector<int> a1;
vector<int> a2;
vector<double> a3;
vector<double> a4;
int getRoot(int x){ //得到people[x]的根节点
while(root[x]!=x){
x=root[x];
}
return x;
}
int f(int x,int y){
if(a4[x]/a2[x]>a4[y]/a2[y])return 1;
else if(a4[x]/a2[x]==a4[y]/a2[y] && a1[x]<a1[y])return 1;
else return 0;
}
int main(){
int N;
int father,mother;//父亲、母亲的编号
int child_amount;//孩子数量
int house_amount,house_S;//房子套数、房子总面积
int box;//装int数据的变量
int mine;
int root1,root2;
vector<int> family;
iIN(0,10000){
root[i]=i;//每个点根节点初始化为自己
}
cin>>N;
iIN(0,N){
family.clear();
cin>>mine>>father>>mother;
if(father!=-1)family.push_back(father);
if(mother!=-1)family.push_back(mother);
cin>>child_amount;
while(child_amount--){
cin>>box;
family.push_back(box);
} //得到了family
cin>>house_amount>>house_S;//得到了房子数量 房子总面积
for(int k=0;k<family.size();k++){ //mine取值最小的那个
if(mine>family[k]){
int box=mine;
mine=family[k];
family[k]=box;
}
}
people.push_back(mine);
house.push_back(house_amount);
S.push_back(house_S);
root1=getRoot(mine);
for(int j=0;j<family.size();j++){
root2=getRoot(family[j]);
root[root2]=root1;
} //并查集合并
}
iIN(0,people.size()){ //生成家庭i 信息保存至a1[i] a2[i] a3[i] a4[i]
if(mark[people[i]]==-1)continue;//people[i]是i人的num
a1.push_back(people[i]);//编号
//a2.push_back(1);//人口数
a3.push_back(house[i]);//房子数量
a4.push_back(S[i]); //房子面积
int r=getRoot(people[i]); //先找根 同根即同家庭
int a2_count=0;
for(int k=0;k<10000;k++){ //计算下这个家庭有多少人
if(getRoot(k)==r)a2_count++;
}
a2.push_back(a2_count);
jIN(i+1,people.size()){
int now=a1.size()-1;//最后一项,也就是刚加入的项
if(getRoot(people[j])==r){ //同一个家庭
if(a1[now]>people[j])a1[now]=people[j];
a3[now]+=house[j];
a4[now]+=S[j];
mark[people[j]]=-1;
}
}
}
vector<int> order;
iIN(0,a1.size()){
order.push_back(i);
}
sort(order.begin(),order.end(),f);
cout<<order.size()<<endl;
jIN(0,order.size()){
int i=order[j];
printf("%04d %d %.3f %.3f\n",a1[i],a2[i],a3[i]/a2[i],a4[i]/a2[i]);
}
return 0;
}