Problem p00817 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
struct UnionFind {
  Int n;
  vector<Int> r, p;
  UnionFind() {}
  UnionFind(Int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(Int x, Int y) { return find(x) == find(y); }
  bool unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return 0;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
    return 1;
  }
};
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n, a, b;
  while (cin >> n >> a >> b, n || a || b) {
    UnionFind uf(a + b);
    UnionFind co(a + b);
    vector<vector<Int>> ng(a + b);
    for (Int i = 0; i < n; i++) {
      Int x, y;
      string s;
      cin >> x >> y >> s;
      x--;
      y--;
      if (s == "yes")
        uf.unite(x, y);
      else {
        ng[x].emplace_back(y);
        ng[y].emplace_back(x);
      }
      co.unite(x, y);
    }
    vector<Int> dp(a + b + 1, 0);
    vector<vector<Int>> bk;
    vector<Int> vs;

    while (1) {
      Int flg = 0;
      for (Int i = 0; i < a + b; i++) {
        if (uf.find(i) == i)
          continue;
        for (Int x : ng[i])
          ng[uf.find(i)].emplace_back(x);
        ng[i].clear();
      }
      for (Int i = 0; i < a + b; i++) {
        if (uf.find(i) != i)
          continue;
        for (Int x : ng[i])
          flg |= uf.unite(x, ng[i][0]);
      }
      if (!flg)
        break;
    }
    dp[0] = 1;
    vector<Int> used(a + b, 0);
    for (Int i = 0; i < a + b; i++) {
      if (used[co.find(i)])
        continue;
      used[co.find(i)] = 1;

      vs.emplace_back(uf.find(i));
      bk.emplace_back(dp);

      Int x = uf.r[uf.find(i)], y = co.r[co.find(i)] - x;
      vector<Int> nx(a + b + 1, 0);
      // cout<<x<<" "<<y<<endl;

      for (Int j = 0; j <= a + b; j++) {
        if (j + x <= a + b)
          nx[j + x] += dp[j];
        if (j + y <= a + b)
          nx[j + y] += dp[j];
      }

      for (Int j = 0; j <= a + b; j++)
        chmin(nx[j], 2);
      swap(dp, nx);
    }
    // for(Int x:dp) cout<<x<<endl;

    if (dp[a] != 1) {
      cout << "no" << endl;
      continue;
    }

    vector<vector<Int>> rks(a + b);
    vector<Int> oth(a + b, -1);
    for (Int i = 0; i < a + b; i++) {
      Int k = uf.find(i);
      rks[co.find(k)].emplace_back(k);
    }

    for (Int i = 0; i < a + b; i++) {
      vector<Int> &v = rks[i];
      sort(v.begin(), v.end());
      v.erase(unique(v.begin(), v.end()), v.end());
      v.emplace_back(-1);
    }

    for (Int i = 0; i < a + b; i++) {
      Int k = uf.find(i);
      oth[k] = rks[co.find(k)][rks[co.find(k)][0] == k];
    }

    bk.emplace_back(dp);
    reverse(vs.begin(), vs.end());
    reverse(bk.begin(), bk.end());
    set<Int> dev;
    Int pos = a;

    // cout<<vs.size()<<":"<<bk.size()<<endl;
    for (Int i = 0; i < (Int)vs.size(); i++) {
      Int x = uf.r[vs[i]], y = co.r[co.find(vs[i])] - x;
      assert(x >= 0 && y >= 0);
      assert((pos >= x && bk[i + 1][pos - x] == 1) ^
             (pos >= y && bk[i + 1][pos - y] == 1));

      if (pos >= x && bk[i + 1][pos - x] == 1) {
        dev.emplace(vs[i]);
        pos -= x;
      } else {
        if (y)
          dev.emplace(oth[vs[i]]);
        pos -= y;
      }
    }
    assert(pos == 0);

    Int cnt = 0;
    for (Int i = 0; i < a + b; i++)
      if (dev.count(uf.find(i)))
        cout << i + 1 << endl, cnt++;

    assert(cnt == a);
    cout << "end" << endl;
  }
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
struct UnionFind {
  Int n;
  vector<Int> r, p;
  UnionFind() {}
  UnionFind(Int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(Int x, Int y) { return find(x) == find(y); }
  void unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }
};
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n, a, b;
  while (cin >> n >> a >> b, n || a || b) {
    UnionFind uf(a + b);
    UnionFind co(a + b);
    for (Int i = 0; i < n; i++) {
      Int x, y;
      string s;
      cin >> x >> y >> s;
      x--;
      y--;
      if (s == "yes")
        uf.unite(x, y);
      co.unite(x, y);
    }
    vector<Int> dp(a + b + 1, 0);
    vector<vector<Int>> bk;
    vector<Int> vs;

    dp[0] = 1;
    vector<Int> used(a + b, 0);
    for (Int i = 0; i < a + b; i++) {
      if (used[co.find(i)])
        continue;
      used[co.find(i)] = 1;

      vs.emplace_back(uf.find(i));
      bk.emplace_back(dp);

      Int x = uf.r[uf.find(i)], y = co.r[co.find(i)] - x;
      vector<Int> nx(a + b + 1, 0);
      // cout<<x<<" "<<y<<endl;

      for (Int j = 0; j <= a + b; j++) {
        if (j + x <= a + b)
          nx[j + x] += dp[j];
        if (j + y <= a + b)
          nx[j + y] += dp[j];
      }

      for (Int j = 0; j <= a + b; j++)
        chmin(nx[j], 2);
      swap(dp, nx);
    }
    // for(Int x:dp) cout<<x<<endl;

    if (dp[a] != 1) {
      cout << "no" << endl;
      continue;
    }

    vector<vector<Int>> rks(a + b);
    vector<Int> oth(a + b, -1);
    for (Int i = 0; i < a + b; i++) {
      Int k = uf.find(i);
      rks[co.find(k)].emplace_back(k);
    }

    for (Int i = 0; i < a + b; i++) {
      vector<Int> &v = rks[i];
      sort(v.begin(), v.end());
      v.erase(unique(v.begin(), v.end()), v.end());
      v.emplace_back(-1);
    }

    for (Int i = 0; i < a + b; i++) {
      Int k = uf.find(i);
      oth[k] = rks[co.find(k)][rks[co.find(k)][0] == k];
    }

    bk.emplace_back(dp);
    reverse(vs.begin(), vs.end());
    reverse(bk.begin(), bk.end());
    set<Int> dev;
    Int pos = a;

    // cout<<vs.size()<<":"<<bk.size()<<endl;
    for (Int i = 0; i < (Int)vs.size(); i++) {
      Int x = uf.r[vs[i]], y = co.r[co.find(vs[i])] - x;
      // assert(x>=0&&y>=0);
      // assert((pos>=x&&bk[i+1][pos-x]==1)^(pos>=y&&bk[i+1][pos-y]==1));

      if (pos >= x && bk[i + 1][pos - x] == 1) {
        dev.emplace(vs[i]);
        pos -= x;
      } else {
        if (y)
          dev.emplace(oth[vs[i]]);
        pos -= y;
      }
    }
    int cnt = 0;
    for (Int i = 0; i < a + b; i++)
      if (dev.count(uf.find(i)))
        cout << i + 1 << endl, cnt++;
    assert(cnt == a);
    cout << "end" << endl;
  }
  return 0;
}