PAT (Advanced Level) Practice 1107 Social Clusters

傷城~ 2023-07-03 03:22 116阅读 0赞

解题方法:并查集
把爱好当成并查集元素。
对于每个人
当爱好只有一个时,不做任何操作。
当爱好大于一个时,两两进行并查集的合并操作。

遍历完后,就可找出,每个cluster的father (father[i]=i)
但是有一个问题:我们为了方便编码,会开辟father[1001] 大小的数组,来记录第 i 个元素的father,初始化时 father[i] = i,
可能爱好 i 并不存在,但是也有father[i]=i。所以我加了个exist数组来记录爱好 i 是否存在。
所以 i 是一个cluster 的根的判别条件为 father[i]==i && exist[i]==true。

还有一个问题,如何知晓每个cluster的人数呢?
我这里用了一个hobby数组,记录第i个人的第一个爱好(每个人至少有一个爱好)
还有一个number数组,记录以 i 为根的cluster 的人数。
接下来遍历hobby数组,对于每个爱好可以找到他的根root,再令number[root]++,即可。

最后排序输出就完事了。

总结:这道题时限是1200ms,但是用并查集3、4ms就可以过,为啥要给这么长时间呢?其实PAT题目做多了,就知道,放宽时间,是为了给暴力解题(或者算法不是很优)的人点分拿。往往最优的代码在很短的时间内就能过,而不那么好的代码,可能会超时1、2个用例。

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <stdio.h>
  4. #include <vector>
  5. #define maxn 1001
  6. using namespace std;
  7. vector<int> cluster;
  8. int father[maxn],number[maxn]={0},hobby[maxn];
  9. bool exist[maxn]={false};
  10. int findfather(int a){
  11. int z = a;
  12. while(a!=father[a]){
  13. a = father[a];
  14. }
  15. while(z!=father[z]){
  16. int m = z;
  17. z=father[z];
  18. father[m]=a;
  19. }
  20. return a;
  21. }
  22. void unio(int a,int b){
  23. int fa=findfather(a);
  24. int fb = findfather(b);
  25. if(fa!=fb){
  26. father[fb]=fa;
  27. }
  28. }
  29. int main()
  30. {
  31. for(int i=0;i<maxn;i++){
  32. father[i]=i;
  33. }
  34. int n;
  35. cin>>n;
  36. for(int i=0;i<n;i++){
  37. int k,a,b;
  38. scanf("%d: %d",&k,&a);
  39. hobby[i]=a;
  40. exist[a]=true;
  41. if(k>1){
  42. for(int i=1;i<k;i++){
  43. scanf("%d",&b);
  44. exist[b]=true;
  45. unio(a,b);
  46. a=b;
  47. }
  48. }
  49. }
  50. for(int i=0;i<n;i++){
  51. int f = findfather(hobby[i]);
  52. number[f]++;
  53. }
  54. for(int i=1;i<maxn;i++){
  55. if(exist[i]==true&&father[i]==i){
  56. cluster.push_back(number[i]);
  57. }
  58. }
  59. sort(cluster.begin(),cluster.end());
  60. cout<<cluster.size()<<endl;
  61. for(int i=cluster.size()-1;i>=0;i--){
  62. cout<<cluster[i];
  63. if(i!=0) cout<<" ";
  64. }
  65. return 0;
  66. }

发表评论

表情:
评论列表 (有 0 条评论,116人围观)

还没有评论,来说两句吧...

相关阅读