思路:
1.用结构体将每一个人的信息存储下来,同时将每一个人的家人也作为一个人存储下来,为了使用这些人的家人部分;
2.设立map标记某一个人是否被遍历过、是否在输入给定的人里(每行输入的第一个id)(为了确定遍历到这个人时要不要加上他的资产);
3.将人以id为key存入map,从头开始遍历,可以解决家族中输出id最小的问题;
4.设立家族结构体,储存相应变量,并编写相应排序规则,每遍历完一个家族,将其存入set;
5.最后以"%04d %d %.3f %.3f
"
格式输出;
代码:
#include<iostream>
#include<map>
#include<vector>
#include<set>
using namespace std;
struct person{
int m,area;
vector<int> v;
};
struct family{
int id,m;
double sets,area;
bool operator < (const family & f) const{
return area==f.area?id<f.id:area>f.area;
}
};
int n,m,sets,area;
map<int,bool> checked,exist;
map<int,person> mp;
set<family> st;
void traversal(int p){
checked[p]=true;
m++;
if(exist[p]){
sets+=mp[p].m;
area+=mp[p].area;
}
for(auto e:mp[p].v)
if(!checked[e]&&~e) traversal(e);
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
int id,k,chd;
vector<int> v(2);
scanf("%d%d%d%d",&id,&v[0],&v[1],&k);
exist[id]=true;
for(int j=0;j<k;j++){
scanf("%d",&chd);
v.push_back(chd);
mp[id].v=v;
for(auto e:v) mp[e].v.push_back(id);
}
scanf("%d%d",&mp[id].m,&mp[id].area);
}
for(auto e:mp){
if(!checked[e.first]&&~e.first){
m=sets=area=0;
traversal(e.first);
family f{e.first,m,sets/(m*1.0),area/(m*1.0)};
st.insert(f);
}
}
printf("%d
",st.size());
for(set<family>::iterator it=st.begin();it!=st.end();it++)
printf("%04d %d %.3f %.3f
",it->id,it->m,it->sets,it->area);
return 0;
}