PAT 1114. Family Property (25) 建图,不要建树

1114. Family Property (25)

时间限制
150 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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 ... Childk M_estate 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; Childi's are the ID's of his/her children;M_estate 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; AVG_sets is the average number of sets of their real estate; and AVG_area 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

这道题的重点在于没必要看成树。换言之,不管对方是爸爸还是儿子,无所谓,反正是和我有关系的人,存起来就行。

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdio.h>
#include<queue>
#include<set>
#include<deque>
using namespace std;
int n;
double sum=0;
double area=0;
int cnt=0;
int minn;
int p=0;
struct ZZZ
{
    double sum;
    double area;
    int cnt;
    int id;
  bool operator < (const ZZZ &A ) const
  {
      if(area!=A.area) return area>A.area;
      return id<A.id;
  }
}last[2000];

struct ZZ
{
    double fortune=0;
    double area=0;
}node[10005];

vector<int> guanxi[10005];   // 存这个人的社会关系

int mark[10005]={0};

void dfs(int x)
{
    mark[x]=1;
    cnt++;
    if(x<minn) minn=x;
    sum+=node[x].fortune;
    area+=node[x].area;
    for(int i=0;i<guanxi[x].size();i++)
    {
       int z=guanxi[x][i];
       if(mark[z]==0) dfs(z);
    }
}


int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int self,ba,ma;
        int k;
        double fortune,areaa;
        cin>>self>>ba>>ma>>k;
        guanxi[self].push_back(self);   //不要忘了把自己存进去!!有些家庭只有一个人,和别人没社会关系
        for(int j=0;j<k;j++)
        {
            int aa;
            cin>>aa;
            guanxi[self].push_back(aa);       //这里必须两方都互存关系,否则一个家庭可能会被误认为两个家庭
            guanxi[aa].push_back(self);       //比如  爸爸->没结婚的独生子女<-妈妈
        }
        if(ba!=-1)  {
                guanxi[self].push_back(ba);
                guanxi[ba].push_back(self);
                     }
        if(ma!=-1) {
                guanxi[self].push_back(ma);
                guanxi[ma].push_back(self);
                 }
        cin>>fortune>>areaa;
        node[self].area=areaa;
        node[self].fortune=fortune;
    }
        for(int i=0;i<10001;i++)
        {
            if(guanxi[i].size()!=0&&mark[i]==0)
            {
               cnt=sum=area=0;
               minn=10000;
               dfs(i);
               last[p].area=area/cnt;
               last[p].cnt=cnt;
               last[p].id=minn;
               last[p].sum=sum/cnt;
               p++;
            }
         }
       sort(last,last+p);
       cout<<p<<endl;
       for(int i=0;i<p;i++)
       {
           printf("%04d %d %.3lf %.3lf\n",last[i].id,last[i].cnt,last[i].sum,last[i].area);
       }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值