AlexNeagu11

RollbackSol

Jan 26th, 2024
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.39 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct StateDSU {
  5. int rootA, rootB, sizeA, sizeB;
  6. StateDSU(int _rootA, int _rootB, int _sizeA, int _sizeB) {
  7. rootA = _rootA;
  8. rootB = _rootB;
  9. sizeA = _sizeA;
  10. sizeB = _sizeB;
  11. }
  12. };
  13.  
  14. class RollbackDSU {
  15. private:
  16. vector<int> par;
  17. vector<int> sz;
  18. vector<StateDSU> states;
  19. vector<int> snapshots;
  20. int setCount;
  21. public:
  22. // constructor
  23. RollbackDSU(int nodeCount) : setCount(nodeCount) {
  24. par.resize(nodeCount + 1);
  25. sz.assign(nodeCount + 1, 1);
  26. for(int i = 1; i <= nodeCount; ++i) {
  27. par[i] = i;
  28. }
  29. }
  30.  
  31. private:
  32. // find the root of the component
  33. int getRoot(int node) {
  34. return node == par[node] ? node : node = getRoot(par[node]);
  35. }
  36.  
  37. public:
  38. void addEdge(int a, int b) {
  39. int rootA = getRoot(a);
  40. int rootB = getRoot(b);
  41. int sizeA = sz[rootA];
  42. int sizeB = sz[rootB];
  43.  
  44. states.push_back(StateDSU(rootA, rootB, sizeA, sizeB));
  45. if(rootA == rootB) {
  46. return;
  47. }
  48.  
  49. setCount--;
  50. if(sizeA >= sizeB) {
  51. par[rootB] = rootA;
  52. sz[rootA] += sizeB;
  53. }
  54. else {
  55. par[rootA] = rootB;
  56. sz[rootB] += sizeA;
  57. }
  58. }
  59.  
  60. bool rollBack() {
  61. if(states.empty()) {
  62. return false;
  63. }
  64.  
  65. StateDSU lastState = states.back();
  66. states.pop_back();
  67.  
  68. int rootA = lastState.rootA;
  69. int rootB = lastState.rootB;
  70. int sizeA = lastState.sizeA;
  71. int sizeB = lastState.sizeB;
  72.  
  73. if(rootA == rootB) {
  74. return true;
  75. }
  76.  
  77. setCount++;
  78. if(sizeA >= sizeB) {
  79. par[rootB] = rootB;
  80. sz[rootA] -= sizeB;
  81. }
  82. else {
  83. par[rootA] = rootA;
  84. sz[rootB] -= sizeA;
  85. }
  86. return true;
  87. }
  88.  
  89. bool lastSnapshotRoll() {
  90. if(snapshots.empty()) {
  91. return false;
  92. }
  93. int lastSnapshot = snapshots.back();
  94. snapshots.pop_back();
  95. while(states.size() > lastSnapshot) {
  96. assert(rollBack());
  97. }
  98. return true;
  99. }
  100.  
  101. void addSnapshot() {
  102. snapshots.push_back((int) states.size());
  103. }
  104.  
  105. int getSetCount() {
  106. return setCount;
  107. }
  108. };
  109.  
  110. int n, m;
  111.  
  112. int main() {
  113. ios_base::sync_with_stdio(false);
  114. cin.tie(0);
  115.  
  116. cin >> n >> m;
  117. RollbackDSU dsu(n);
  118.  
  119. while(m--) {
  120. string op;
  121. cin >> op;
  122. if(op[0] == 'p')
  123. dsu.addSnapshot();
  124. else if(op[0] == 'r') {
  125. assert(dsu.lastSnapshotRoll());
  126. cout << dsu.getSetCount() << '\n';
  127. }
  128. else {
  129. int x, y;
  130. cin >> x >> y;
  131. dsu.addEdge(x, y);
  132. cout << dsu.getSetCount() << '\n';
  133. }
  134. }
  135.  
  136. return 0;
  137. }
Advertisement
Add Comment
Please, Sign In to add comment