fork download
  1. // union find
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4.  
  5. const int N = 200000; // тогтмол хувьсагч
  6.  
  7. int n; // оройн тоо
  8. int q; // хүсэлтийн тоо
  9. int s[N]; // s[x] нь x гэсэн дээд эцэгтэй компонентийн хэмжээ
  10. int comp; // нийт компонентийн тоо
  11. int par[N]; // par[x] нь x оройн эцгийг хадгална.
  12.  
  13. int find(int x) { // x оройн дээд эцгийг олох функц
  14. if(x == par[x]) { // x оройн эцэг өөрөө гэдэг нь хамгийн дээд орой мөн
  15. return x; // тиймээс x оройг буцаана.
  16. }
  17.  
  18. // эсрэг тохиолдолд
  19. // par[x] оройн дээд эцэг нь x оройн дээд эцэг тул par[x] оройн
  20. // дээд эцгийг олно.
  21.  
  22. int root = find( par[x] );
  23.  
  24. // root нь дээд эцэг бөгөөд
  25. // x оройн эцгийг root гэж оноосноор холболтын урт багасна.
  26. // ингэснээр бидэнд ашигтай.
  27.  
  28. par[x] = root;
  29. return root;
  30. }
  31.  
  32. int main() {
  33. cin >> n; // оройн тоо
  34. comp = n; // n ширхэг компонент байгаа.
  35.  
  36. for(int i = 1; i <= n; i++) {
  37. par[i] = i; // i оройн эцэг нь өөрөө
  38. s[i] = 1; // хэмжээ нь 1
  39. }
  40.  
  41. cin >> q; // хүсэлтийн тоо
  42.  
  43. while(q--) {
  44. int x, y; // холбох 2 орой
  45. cin >> x >> y;
  46.  
  47. int rootX = find(x); // x оройн дээд эцгийг олно.
  48. int rootY = find(y); // y оройн дээд эцгийг олно.
  49.  
  50. if(rootX == rootY) { // анхны 2 оройн дээд эцэг нь ижил гэдэг нь
  51. // нэг компонентэд энэ 2 орой оршиж байна.
  52. // тиймээс юу ч хийх шаардлагагүй.
  53. } else { // эсрэг тохиолдолд нэгтгэх ёстой.
  54. // 2 компонент нэгдэж байгаа тул нийт компонентийн тоо нэгээр хасагдана.
  55. comp--;
  56. if(s[rootX] > s[rootY]) { // хэмжээ ихэд нь хэмжээ багатай
  57. // компонентийг холбоно.
  58. par[rootY] = rootX; // rootY-н эцгийг rootX болгоно.
  59. s[rootX] += s[rootY]; // rootX эцэгтэй компонентийн хэмжээ нь нэмэгдэнэ.
  60. s[rootY] = 0;
  61. } else {
  62. par[rootX] = rootY; // rootX-н эцгийг rootY болгоно.
  63. s[rootY] += s[rootX]; // rootY эцэгтэй компонентийн хэмжээ нь нэмэгдэнэ.
  64. s[rootX] = 0;
  65. }
  66. }
  67. cout << comp << endl;
  68. }
  69.  
  70. return 0;
  71. }
Success #stdin #stdout 0s 16792KB
stdin
4 1
1 2
stdout
3