题目分析:
典型的union-find 算法
想法: 先不着急 union 因为每一个人的房产信息不知道 所以先输入所有信息 同时保留与自己有关系的每一个人
待初始化每一个人的房产信息后,再union
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+1; 4 struct T { 5 int id; 6 int p_n; 7 int w_n; 8 int sum; 9 double avg; 10 }; 11 T a[N]; 12 int father [N]; 13 bool isok[N];//这个号码是否出现 14 vector < vector <int> > g(N);// 保存每一个与自己有关系的人 15 int n; 16 int _find (int x) { 17 if (father[x]!=x) 18 father[x]=_find(father[x]); 19 return father[x]; 20 } 21 bool cmp (T x,T y) { 22 if (x.avg==y.avg) 23 return x.id<y.id; 24 return x.avg>y.avg; 25 } 26 int main () 27 { 28 for (int i=0;i<N;i++) { 29 father[i]=i; 30 a[i].p_n=1; 31 a[i].w_n=a[i].sum=0; 32 } 33 scanf ("%d",&n); 34 for (int i=1;i<=n;i++) { 35 int id,f_id,m_id,k; 36 scanf ("%d %d %d %d",&id,&f_id,&m_id,&k); 37 isok[id]=1; 38 if (f_id>=0) { isok[f_id]=1; g[id].push_back(f_id);} 39 if (m_id>=0) { isok[m_id]=1; g[id].push_back(m_id);} 40 for (int j=1;j<=k;j++) { 41 int x; scanf ("%d",&x); 42 isok[x]=1; 43 g[id].push_back(x); 44 } 45 scanf ("%d %d",&a[id].w_n,&a[id].sum); 46 } 47 for (int i=0;i<N;i++) 48 if (isok[i]) { 49 for (int j=0;j<g[i].size();j++) { 50 int next=g[i][j]; 51 int k1=_find(i); 52 int k2=_find(next); 53 if (k1<k2) { 54 father[k2]=k1; 55 a[k1].p_n+=a[k2].p_n; 56 a[k1].w_n+=a[k2].w_n; 57 a[k1].sum+=a[k2].sum; 58 } 59 else if (k1>k2){ 60 father[k1]=k2; 61 a[k2].p_n+=a[k1].p_n; 62 a[k2].w_n+=a[k1].w_n; 63 a[k2].sum+=a[k1].sum; 64 } 65 } 66 } 67 T ans[1007]; int t=0; 68 for (int i=0;i<N;i++) { 69 if (isok[i]&&father[i]==i) { 70 ans[++t]=a[i]; 71 ans[t].id=i; 72 ans[t].avg=(double) a[i].sum/a[i].p_n; 73 } 74 } 75 printf ("%d ",t); 76 sort (ans+1,ans+t+1,cmp); 77 for (int i=1;i<=t;i++) 78 printf ("%04d %d %.3lf %.3lf ",ans[i].id,ans[i].p_n,(double)ans[i].w_n/ans[i].p_n,ans[i].avg); 79 return 0; 80 }