ThegeekKnight16

Union-find com rollback

Aug 6th, 2025
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.24 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. vector<int> pai, sub;
  4. int qSets = 0, temp = 0;
  5. stack<tuple<int, int, int>> opers;
  6.  
  7. int find(int v) {return (v == pai[v] ? v : find(pai[v]));}
  8. void une(int x, int y)
  9. {
  10.     x = find(x); y = find(y);
  11.     if (x == y) {opers.emplace(-1, -1, ++temp); return;}
  12.     if (sub[x] < sub[y]) swap(x, y);
  13.     opers.emplace(x, y, ++temp);
  14.     pai[y] = x; sub[x] += sub[y]; --qSets;
  15. }
  16. void rollback()
  17. {
  18.     if (opers.empty()) return;
  19.     auto [x, y, t] = opers.top(); opers.pop();
  20.     if (x == -1) return;
  21.     pai[y] = y; sub[x] -= sub[y]; ++qSets;
  22. }
  23.  
  24. int main()
  25. {
  26.     ios_base::sync_with_stdio(false);
  27.     cin.tie(NULL);
  28.     int N, M; cin >> N >> M;
  29.     pai.resize(N+1); iota(pai.begin(), pai.end(), 0);
  30.     sub.resize(N+1); fill(sub.begin(), sub.end(), 1);
  31.     qSets = N;
  32.  
  33.     vector<int> versions;
  34.     while (M--)
  35.     {
  36.         string type; cin >> type;
  37.         if (type == "union")
  38.         {
  39.             int x, y;
  40.             cin >> x >> y;
  41.             une(x, y);
  42.             cout << qSets << '\n';
  43.         }
  44.         else if (type == "persist") versions.push_back(temp);
  45.         else //rollback
  46.         {
  47.             //enquanto o tempo da operacao for maior que o da versao, dou rollback
  48.             while (!opers.empty() && get<2>(opers.top()) > versions.back()) rollback();
  49.             versions.pop_back();
  50.             cout << qSets << '\n';
  51.         }
  52.     }
  53. }
Advertisement
Add Comment
Please, Sign In to add comment