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

#include <bits/stdc++.h>
#define N 1001
using namespace std;
int n, p1, p2;
typedef pair<int, int> P;
vector<P> G[N], rG[N];
vector<P> A;

int used[N], god, devil;
vector<int> Idx[N];
int Sta[N];

void dfs(int pos, int sta) {
  Idx[A.size()].push_back(pos);
  Sta[pos] = sta;

  for (P nx : G[pos]) {
    int npos = nx.first;
    int nsta = sta ^ (!nx.second);
    if (used[npos])
      assert(Sta[npos] == nsta);
    if (used[npos]++)
      continue;
    god += nsta;
    devil += !nsta;
    dfs(npos, nsta);
  }

  for (P nx : rG[pos]) {
    int npos = nx.first;
    int nsta = sta ^ (!nx.second);
    if (used[npos])
      assert(Sta[npos] == nsta);
    if (used[npos]++)
      continue;
    god += nsta;
    devil += !nsta;
    dfs(npos, nsta);
  }
}

void Push(vector<int> &res, int sta, int i) {
  for (int p : Idx[i])
    if (sta == Sta[p])
      res.push_back(p + 1);
}

int dp[N][N];
vector<int> DP() {
  memset(dp, 0, sizeof(dp));
  dp[0][0] = 1;
  int n = A.size();
  for (int i = 0; i < n; i++) {
    int a = A[i].first;
    int b = A[i].second;
    for (int j = 0; j <= p1; j++) {
      dp[i + 1][j + a] += dp[i][j];
      dp[i + 1][j + b] += dp[i][j];
      dp[i + 1][j + a] = min(2, dp[i + 1][j + a]);
      dp[i + 1][j + b] = min(2, dp[i + 1][j + b]);
    }
  }

  if (dp[n][p1] != 1)
    return vector<int>();
  vector<int> res;
  int god = p1;
  for (int i = n - 1; i >= 0; i--) {
    int a = A[i].first;
    int b = A[i].second;
    if (god - a >= 0 && dp[i][god - a] == 1)
      Push(res, 1, i), god -= a;
    else if (god - b >= 0 && dp[i][god - b] == 1)
      Push(res, 0, i), god -= b;
    else
      exit(1);
  }
  assert(god == 0);
  sort(res.begin(), res.end());
  return res;
}

int main() {
  while (1) {
    cin >> n >> p1 >> p2;
    if (!n && !p1 && !p2)
      return 0;

    A.clear();
    memset(used, 0, sizeof(used));
    memset(Sta, -1, sizeof(Sta));
    for (int i = 0; i < N; i++)
      Idx[i].clear(), G[i].clear(), rG[i].clear();

    for (int i = 0, x, y; i < n; i++) {
      string str;
      cin >> x >> y >> str;
      x--, y--;
      G[x].push_back(P(y, str == "yes"));
      rG[y].push_back(P(x, str == "yes"));
    }

    for (int i = 0; i < p1 + p2; i++) {
      if (used[i]++)
        continue;
      god = 1, devil = 0;
      dfs(i, 1);
      A.push_back(P(god, devil));
    }

    vector<int> ans = DP();
    if (p1 && ans.empty())
      cout << "no" << endl;
    else {
      for (int p : ans)
        cout << p << endl;
      cout << "end" << endl;
    }
  }
  return 0;
}

Error: -6
79e8b94d-e850-4070-807e-d5f4e60391c4.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00817/C++/s592585319.cpp:78: int main(): Assertion `p1 && p2' failed.


Fixed submission:

#include <bits/stdc++.h>
#define N 1001
using namespace std;
int n, p1, p2;
typedef pair<int, int> P;
vector<P> G[N], rG[N];
vector<P> A;

int used[N], god, devil;
vector<int> Idx[N];
int Sta[N];

void dfs(int pos, int sta) {
  Idx[A.size()].push_back(pos);
  Sta[pos] = sta;

  for (P nx : G[pos]) {
    int npos = nx.first;
    int nsta = sta ^ (!nx.second);
    if (used[npos])
      assert(Sta[npos] == nsta);
    if (used[npos]++)
      continue;
    god += nsta;
    devil += !nsta;
    dfs(npos, nsta);
  }

  for (P nx : rG[pos]) {
    int npos = nx.first;
    int nsta = sta ^ (!nx.second);
    if (used[npos])
      assert(Sta[npos] == nsta);
    if (used[npos]++)
      continue;
    god += nsta;
    devil += !nsta;
    dfs(npos, nsta);
  }
}

void Push(vector<int> &res, int sta, int i) {
  for (int p : Idx[i])
    if (sta == Sta[p])
      res.push_back(p + 1);
}

int dp[N][N];
vector<int> DP() {
  memset(dp, 0, sizeof(dp));
  dp[0][0] = 1;
  int n = A.size();
  for (int i = 0; i < n; i++) {
    int a = A[i].first;
    int b = A[i].second;
    for (int j = 0; j <= p1; j++) {
      dp[i + 1][j + a] += dp[i][j];
      dp[i + 1][j + b] += dp[i][j];
      dp[i + 1][j + a] = min(2, dp[i + 1][j + a]);
      dp[i + 1][j + b] = min(2, dp[i + 1][j + b]);
    }
  }

  if (dp[n][p1] != 1)
    return vector<int>();
  vector<int> res;
  int god = p1;
  for (int i = n - 1; i >= 0; i--) {
    int a = A[i].first;
    int b = A[i].second;
    if (god - a >= 0 && dp[i][god - a] == 1)
      Push(res, 1, i), god -= a;
    else if (god - b >= 0 && dp[i][god - b] == 1)
      Push(res, 0, i), god -= b;
    else
      exit(1);
  }
  assert(god == 0);
  sort(res.begin(), res.end());
  return res;
}

int main() {
  while (1) {
    cin >> n >> p1 >> p2;
    assert(p1 && p2);
    if (!n && !p1 && !p2)
      return 0;

    A.clear();
    memset(used, 0, sizeof(used));
    memset(Sta, -1, sizeof(Sta));
    for (int i = 0; i < N; i++)
      Idx[i].clear(), G[i].clear(), rG[i].clear();

    for (int i = 0, x, y; i < n; i++) {
      string str;
      cin >> x >> y >> str;
      x--, y--;
      G[x].push_back(P(y, str == "yes"));
      rG[y].push_back(P(x, str == "yes"));
    }

    for (int i = 0; i < p1 + p2; i++) {
      if (used[i]++)
        continue;
      god = 1, devil = 0;
      dfs(i, 1);
      A.push_back(P(god, devil));
    }

    vector<int> ans = DP();
    if (ans.empty())
      cout << "no" << endl;
    else {
      for (int p : ans)
        cout << p << endl;
      cout << "end" << endl;
    }
  }
  return 0;
}