题目分析:

  典型的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\n",t);
76     sort (ans+1,ans+t+1,cmp);
77     for (int i=1;i<=t;i++)
78         printf ("%04d %d %.3lf %.3lf\n",ans[i].id,ans[i].p_n,(double)ans[i].w_n/ans[i].p_n,ans[i].avg);
79     return 0;
80 }