题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744

并查集的基本应用,有几个地方是模版务必记一下

  1. find_father()函数
  2. Union()函数
  3. 初始化函数init()也可以直接写在主函数里
  4. 50到58行的代码

代码

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. using namespace std;
  5. const int maxn = 1010;
  6. int m, n;
  7. int father[maxn];
  8. int is_root[maxn] = {0};
  9. int course[maxn];
  10. int find_father(int i){
  11. if(father[i] == i) return i;
  12. else{
  13. int f = find_father(father[i]);
  14. father[i] = f;
  15. return f;
  16. }
  17. }
  18. void Union(int a, int b){
  19. int faA = find_father(a);
  20. int faB = find_father(b);
  21. if(faA!=faB) father[faA] = faB;
  22. }
  23. void init(){
  24. for(int i = 1; i <= n; i++){
  25. father[i] = i;
  26. is_root[i] = false;
  27. }
  28. }
  29. bool cmp(int a, int b){
  30. return a > b;
  31. }
  32. int main(){
  33. int temp;
  34. scanf("%d", &n);
  35. init();
  36. for(int i = 1; i <= n; i++){
  37. scanf("%d:", &m);
  38. for(int j = 0; j < m; j++){
  39. scanf("%d", &temp);
  40. if(course[temp] == 0) course[temp] = i;
  41. Union(i, find_father(course[temp]));
  42. }
  43. }
  44. for(int i = 1; i <= n; i++){
  45. is_root[find_father(i)]++;
  46. }
  47. int count = 0;
  48. for(int i = 1; i <= n; i++){
  49. if(is_root[i] != 0){
  50. count++;
  51. }
  52. }
  53. printf("%d\n", count);
  54. sort(is_root + 1, is_root + n + 1, cmp);
  55. for(int i = 1; i <= count; i++){
  56. printf("%d", is_root[i]);
  57. if(i != count) printf(" ");
  58. }
  59. return 0;
  60. }