【1114】Family Property (25分)【并查集】

举报
野猪佩奇996 发表于 2022/01/22 23:47:54 2022/01/22
【摘要】 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<math.h>#include<string.h>#include<algorithm> #include<map>#inclu...

  
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. #include<string.h>
  6. #include<algorithm>
  7. #include<map>
  8. #include<vector>
  9. #include<queue>
  10. using namespace std;
  11. struct DATA{
  12. int id,fid,mid,num,area;
  13. int cid[10];//这个人node的孩子数组cid[]
  14. }data[1005];
  15. struct node{
  16. int id,people;//people为家庭总人数
  17. double num,area;
  18. bool flag;
  19. }ans[10000];
  20. int father[10000];
  21. bool visit[10000];
  22. int findfather(int x){
  23. while(x!=father[x])//如果不是根结点,继续循环
  24. x=father[x];//获得自己的父亲结点
  25. return x;
  26. }
  27. void Union(int a,int b){
  28. int faA=findfather(a);//查找a的根结点
  29. int faB=findfather(b);//查找b的根结点
  30. //if(faA!=faB){//如果不属于同一个集合
  31. // father[faA]=faB;//合并
  32. if(faA>faB)
  33. father[faA]=faB;
  34. else if(faA<faB)
  35. father[faB]=faA;
  36. }
  37. int cmp1(node a,node b){
  38. if(a.area!=b.area)
  39. return a.area>b.area;//按人均地面积降序
  40. else
  41. return a.id<b.id;//按姓名编号的升序
  42. }
  43. int main(){
  44. int n,k,cnt=0;
  45. scanf("%d",&n);//n行的数据需要读入
  46. for(int i=0;i<10000;i++)
  47. father[i]=i;//初始化并查集
  48. for(int i=0;i<n;i++){//以下n行读取
  49. scanf("%d %d %d %d",&data[i].id,&data[i].fid,
  50. &data[i].mid,&k);
  51. visit[data[i].id]=true;//标记出现的人
  52. if(data[i].fid!=-1){//如果老爸还没挂
  53. visit[data[i].fid]=true;
  54. Union(data[i].fid,data[i].id);
  55. }
  56. if(data[i].mid!=-1){//如果老妈还没挂
  57. visit[data[i].mid]=true;
  58. Union(data[i].mid,data[i].id);
  59. }
  60. for(int j=0;j<k;j++){
  61. scanf("%d",&data[i].cid[j]);
  62. visit[data[i].cid[j]]=true;
  63. Union(data[i].cid[j],data[i].id);
  64. }
  65. scanf("%d %d",&data[i].num,&data[i].area);
  66. }
  67. for(int i=0;i<n;i++){
  68. int id=findfather(data[i].id);
  69. ans[id].id=id;
  70. ans[id].num+=data[i].num;//奇妙的累加
  71. ans[id].area+=data[i].area;
  72. ans[id].flag=true;//不可删,代表该个家庭存在
  73. }
  74. for(int i=0;i<10000;i++){
  75. if(visit[i])
  76. //如果有该人,注意不能再上面的for(n行)里统计
  77. //因为每行可能还有多个人
  78. ans[findfather(i)].people++;
  79. if(ans[i].flag)
  80. cnt++;//统计家庭数
  81. }
  82. for(int i=0;i<10000;i++){
  83. if(ans[i].flag){
  84. //ans[i].num=(double)(ans[i].num*1.0/ans[i].people);
  85. ans[i].num=(ans[i].num*1.0/ans[i].people);
  86. //把double去掉也是可以的
  87. //ans[i].area=(double)(ans[i].area*1.0/ans[i].people);
  88. ans[i].area=(ans[i].area*1.0/ans[i].people);
  89. }
  90. }
  91. sort(ans,ans+10000,cmp1);
  92. printf("%d\n",cnt);
  93. for(int i=0;i<cnt;i++)
  94. printf("%04d %d %.3f %.3f\n",ans[i].id,ans[i].people,ans[i].num,ans[i].area);
  95. system("pause");
  96. return 0;
  97. }

 

文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。

原文链接:andyguo.blog.csdn.net/article/details/103941463

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。