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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
  vector<int> par;
  int cnt;
  UnionFind(int size_) : par(size_, -1), cnt(size_) {}
  void unite(int x, int y) {
    if ((x = find(x)) != (y = find(y))) {
      if (par[y] < par[x])
        swap(x, y);
      par[x] += par[y];
      par[y] = x;
      cnt--;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
  int size(int x) { return -par[find(x)]; }
  int size() { return cnt; }
};

typedef pair<int, int> P; // y, lie
vector<P> G[600];
vector<P> Gr[600];
int lie[600];

void dfs(int v, bool &ok) {
  for (auto x : G[v]) {
    int u = x.first, l = x.second;
    if (lie[u] == -1) {
      lie[u] = l ^ lie[v];
      dfs(u, ok);
    } else {
      int a = l ^ lie[v];
      if (lie[u] != a) {
        ok = false;
      }
    }
  }
  for (auto x : Gr[v]) {
    int u = x.first, l = x.second;
    if (lie[u] == -1) {
      lie[u] = l ^ lie[v];
      dfs(u, ok);
    } else {
      int a = l ^ lie[v];
      if (lie[u] != a) {
        ok = false;
      }
    }
  }
}

set<int> es[600][2];
int exist[600][2];
int dp[610][610];
int pre[610][610];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  int n, engel, devil;
  while (cin >> n >> engel >> devil, n + engel + devil) {
    int N = engel + devil;
    memset(exist, 0, sizeof exist);
    for (int i = 0; i < N; i++) {
      G[i].clear();
      Gr[i].clear();
    }

    UnionFind uf(N);
    for (int i = 0; i < n; i++) {
      int x, y;
      string s;
      cin >> x >> y >> s;
      x--, y--;
      G[x].push_back({y, s == "no"});
      Gr[y].push_back({x, s == "no"});
      uf.unite(x, y);
    }

    vector<vector<int>> group;
    for (int i = 0; i < N; i++) {
      int p = uf.find(i);
      if (p != i)
        continue;
      vector<int> g = {i};
      for (int j = 0; j < N; j++) {
        if (i != j && uf.find(j) == i)
          g.push_back(j);
      }
      group.push_back(g);
    }

    for (int i = 0; i < group.size(); i++) {
      es[i][0].clear();
      es[i][1].clear();
    }

    bool ok = true;
    for (int gi = 0; gi < group.size() && ok; gi++) {
      const auto &g = group[gi];
      int p = g.front();

      for (int i = 0; i < 2; i++) {
        for (auto x : g) {
          lie[x] = -1;
        }
        lie[p] = i;
        bool dfsok = true;
        dfs(p, dfsok);
        if (!dfsok)
          break;
        exist[gi][i] = 1;
        for (int j = 0; j < g.size(); j++) {
          if (lie[g[j]] == 0)
            es[gi][i].insert(g[j]);
        }
      }

      // ???????????????????????????????????????
      if (exist[gi][0] == 0 && exist[gi][1] == 0) {
        ok = false;
        break;
      }
      // ??????????????°?????????????????????2?????§?????????NG
      if (exist[gi][0] && exist[gi][1] &&
          es[gi][0].size() == es[gi][1].size()) {
        ok = false;
        break;
      }
    }
    if (!ok) {
      cout << "no" << endl;
      continue;
    }

    memset(dp, 0, sizeof dp);
    dp[0][0] = 1;
    for (int i = 0; i < group.size(); i++) {
      for (int j = 0; j <= N; j++) {
        if (dp[i][j] == 0)
          continue;
        for (int k = 0; k < 2; k++) {
          if (exist[i][k] == 0)
            continue;

          int en = es[i][k].size();
          dp[i + 1][j + en] += dp[i][j];
          dp[i + 1][j + en] = min(dp[i + 1][j + en], 1000);
          pre[i + 1][j + en] = k;
        }
      }
    }

    if (dp[group.size()][engel] != 1) {
      cout << "no" << endl;
      continue;
    }

    set<int> ans;
    for (int i = group.size(); i >= 1; i--) {
      int k = pre[i][engel];
      const auto &engels = es[i - 1][k];
      int en = engels.size();
      for (auto e : engels) {
        ans.insert(e);
      }
      engel -= en;
    }
    for (auto e : ans) {
      cout << e + 1 << endl;
    }
    cout << "end" << endl;
    // getchar();
  }
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
  vector<int> par;
  int cnt;
  UnionFind(int size_) : par(size_, -1), cnt(size_) {}
  void unite(int x, int y) {
    if ((x = find(x)) != (y = find(y))) {
      if (par[y] < par[x])
        swap(x, y);
      par[x] += par[y];
      par[y] = x;
      cnt--;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); }
  int size(int x) { return -par[find(x)]; }
  int size() { return cnt; }
};

typedef pair<int, int> P; // y, lie
vector<P> G[600];
vector<P> Gr[600];
int lie[600];

void dfs(int v, bool &ok) {
  for (auto x : G[v]) {
    int u = x.first, l = x.second;
    if (lie[u] == -1) {
      lie[u] = l ^ lie[v];
      dfs(u, ok);
    } else {
      int a = l ^ lie[v];
      if (lie[u] != a) {
        ok = false;
      }
    }
  }
  for (auto x : Gr[v]) {
    int u = x.first, l = x.second;
    if (lie[u] == -1) {
      lie[u] = l ^ lie[v];
      dfs(u, ok);
    } else {
      int a = l ^ lie[v];
      if (lie[u] != a) {
        ok = false;
      }
    }
  }
}

set<int> es[600][2];
int exist[600][2];
int dp[610][610];
int pre[610][610];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  int n, engel, devil;
  while (cin >> n >> engel >> devil, n + engel + devil) {
    int N = engel + devil;
    memset(exist, 0, sizeof exist);
    for (int i = 0; i < N; i++) {
      G[i].clear();
      Gr[i].clear();
    }

    UnionFind uf(N);
    for (int i = 0; i < n; i++) {
      int x, y;
      string s;
      cin >> x >> y >> s;
      x--, y--;
      G[x].push_back({y, s == "no"});
      Gr[y].push_back({x, s == "no"});
      uf.unite(x, y);
    }

    vector<vector<int>> group;
    for (int i = 0; i < N; i++) {
      int p = uf.find(i);
      if (p != i)
        continue;
      vector<int> g = {i};
      for (int j = 0; j < N; j++) {
        if (i != j && uf.find(j) == i)
          g.push_back(j);
      }
      group.push_back(g);
    }

    for (int i = 0; i < group.size(); i++) {
      es[i][0].clear();
      es[i][1].clear();
    }

    bool ok = true;
    for (int gi = 0; gi < group.size() && ok; gi++) {
      const auto &g = group[gi];
      int p = g.front();

      for (int i = 0; i < 2; i++) {
        for (auto x : g) {
          lie[x] = -1;
        }
        lie[p] = i;
        bool dfsok = true;
        dfs(p, dfsok);
        if (!dfsok)
          break;
        exist[gi][i] = 1;
        for (int j = 0; j < g.size(); j++) {
          if (lie[g[j]] == 0)
            es[gi][i].insert(g[j]);
        }
      }

      // ???????????????????????????????????????
      if (exist[gi][0] == 0 && exist[gi][1] == 0) {
        ok = false;
        break;
      }
      // ??????????????°?????????????????????2?????§?????????NG
      if (exist[gi][0] && exist[gi][1] &&
          es[gi][0].size() == es[gi][1].size()) {
        ok = false;
        break;
      }
    }
    if (!ok) {
      cout << "no" << endl;
      continue;
    }

    memset(dp, 0, sizeof dp);
    dp[0][0] = 1;
    for (int i = 0; i < group.size(); i++) {
      for (int j = 0; j <= N; j++) {
        if (dp[i][j] != 1)
          continue;
        for (int k = 0; k < 2; k++) {
          if (exist[i][k] == 0)
            continue;

          int en = es[i][k].size();
          dp[i + 1][j + en] += 1;
          pre[i + 1][j + en] = k;
        }
      }
    }

    if (dp[group.size()][engel] != 1) {
      cout << "no" << endl;
      continue;
    }

    set<int> ans;
    for (int i = group.size(); i >= 1; i--) {
      int k = pre[i][engel];
      const auto &engels = es[i - 1][k];
      int en = engels.size();
      for (auto e : engels) {
        ans.insert(e);
      }
      engel -= en;
    }
    for (auto e : ans) {
      cout << e + 1 << endl;
    }
    cout << "end" << endl;
    getchar();
  }
}