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

#include <bits/stdc++.h>

using namespace std;

struct Bipartite_Matching {
  vector<vector<int>> graph;
  vector<int> match, alive, used;
  int timestamp = 0;

  Bipartite_Matching(int n) {
    graph.resize(n);
    alive.assign(n, 1);
    used.assign(n, 0);
    match.assign(n, -1);
  }

  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  bool dfs(int v) {
    used[v] = timestamp;
    for (int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if (alive[u] == 0)
        continue;
      if (w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }

  int bipartite_matching() {
    int ret = 0;
    for (int i = 0; i < graph.size(); i++) {
      if (alive[i] == 0)
        continue;
      if (match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  }

  int add(int k) {
    alive[k] = 1;
    ++timestamp;
    return (dfs(k));
  }

  int kill(int k) {
    alive[k] = 0;
    if (match[k] == -1)
      return (0);
    match[match[k]] = -1;
    ++timestamp;
    int ret = dfs(match[k]);
    match[k] = -1;
    return (ret - 1);
  }
};

const int dx[] = {-1, 0, 1};
const int dy[][3] = {{0, -1, 0}, {0, 1, 0}};

const int vx[2][5][3] = {
    {{1, 2, 3}, {1, 1, 2}, {1, 1, 2}},
    {{1, 2, 3}, {1, 1, 2}, {0, 1, 1}, {1, 1, 2}, {0, 1, 1}},

};
const int vy[2][5][3] = {
    {{0, 0, 0}, {0, 1, 1}, {0, 1, 0}},
    {{0, 0, 0}, {-1, 0, -1}, {1, -1, 0}, {-1, 0, 0}, {1, 1, 2}}};

bool check(int *x, int *y) {
  vector<pair<int, int>> s(4);
  for (int i = 0; i < 4; i++)
    s[i] = {x[i], y[i]};
  sort(begin(s), end(s));
  s.erase(unique(begin(s), end(s)), end(s));
  if (s.size() == 3)
    return (false);

  bool mod = (s[0].first + s[0].second) % 2 != 0;
  for (int i = 0; i < 5; i++) {
    bool flag = true;
    for (int j = 1; j < s.size(); j++) {
      if (s[j].first - s[0].first != vx[mod][i][j - 1])
        flag = false;
      if (s[j].second - s[0].second != vy[mod][i][j - 1])
        flag = false;
    }
    if (flag)
      return (true);
  }
  return (false);
}

int main() {
  int N;
  int x[5000][4], y[5000][4];

  while (scanf("%d", &N), N) {

    int failed_count = 0;
    vector<pair<int, int>> enable[N], press;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 3; j++) {
        scanf("%d %d", &x[i][j], &y[i][j]);
      }
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < 3; k++) {
          x[i][3] = x[i][j] + dx[k];
          y[i][3] = y[i][j] + dy[(x[i][j] + y[i][j]) % 2 != 0][k];
          if (check(x[i], y[i]))
            enable[i].emplace_back(x[i][3], y[i][3]);
        }
      }

      sort(begin(enable[i]), end(enable[i]));
      enable[i].erase(unique(begin(enable[i]), end(enable[i])), end(enable[i]));
      for (auto &p : enable[i])
        press.emplace_back(p);
      if (enable[i].empty())
        failed_count++;
    }
    sort(begin(press), end(press));
    press.erase(unique(begin(press), end(press)), end(press));
    Bipartite_Matching flow(N + press.size());
    for (int i = 0; i < N; i++) {
      for (auto &p : enable[i]) {
        auto s = lower_bound(begin(press), end(press), p) - begin(press);
        flow.add_edge(i, N + s);
      }
    }
    int cnt = 0;

    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 3; j++) {
        auto q = make_pair(x[i][j], y[i][j]);
        auto p = lower_bound(begin(press), end(press), q);
        if (p == end(press))
          continue;
        if (*p == q)
          flow.kill(N + p - begin(press)), ++cnt;
      }
    }
    auto match = flow.bipartite_matching();
    if (match == N) {
      puts("Valid");
    } else {
      vector<int> ret;
      if (failed_count <= 1 && match >= N - 4) {
        for (int i = 0; i < N; i++) {
          for (int j = 0; j < 3; j++) {
            auto q = make_pair(x[i][j], y[i][j]);
            auto p = lower_bound(begin(press), end(press), q);
            if (p == end(press))
              continue;
            if (*p == q)
              match += flow.add(N + p - begin(press));
          }
          match += flow.kill(i);
          if (match == N - 1)
            ret.push_back(i);
          match += flow.add(i);
          for (int j = 0; j < 3; j++) {
            auto q = make_pair(x[i][j], y[i][j]);
            auto p = lower_bound(begin(press), end(press), q);
            if (p == end(press))
              continue;
            if (*p == q)
              match += flow.kill(N + p - begin(press));
          }
        }
      }

      if (ret.empty()) {
        puts("Invalid");
      } else {
        puts("Remove");
        for (int k : ret)
          printf("%d\\n", k + 1);
      }
    }
  }
}

Error: -6
efd79b9d-0831-458f-81cb-c3cd4f1c2c25.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p01625/C++/s770937301.cpp:63: int Bipartite_Matching::kill(int): Assertion `alive[k] == 0' failed.


Fixed submission:

#include <bits/stdc++.h>

using namespace std;

struct Bipartite_Matching {
  vector<vector<int>> graph;
  vector<int> match, alive, used;
  int timestamp = 0;

  Bipartite_Matching(int n) {
    graph.resize(n);
    alive.assign(n, 1);
    used.assign(n, 0);
    match.assign(n, -1);
  }

  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  bool dfs(int v) {
    used[v] = timestamp;
    for (int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if (alive[u] == 0)
        continue;
      if (w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }

  int bipartite_matching() {
    int ret = 0;
    for (int i = 0; i < graph.size(); i++) {
      if (alive[i] == 0)
        continue;
      if (match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  }

  int add(int k) {
    assert(alive[k] == 1);
    alive[k] = 1;
    ++timestamp;
    return (dfs(k));
  }

  int kill(int k) {
    assert(alive[k] == 0);
    alive[k] = 0;
    if (match[k] == -1)
      return (0);
    match[match[k]] = -1;
    ++timestamp;
    int ret = dfs(match[k]);
    match[k] = -1;
    return (ret - 1);
  }
};

const int dx[] = {-1, 0, 1};
const int dy[][3] = {{0, -1, 0}, {0, 1, 0}};

const int vx[2][5][3] = {
    {{1, 2, 3}, {1, 1, 2}, {1, 1, 2}},
    {{1, 2, 3}, {1, 1, 2}, {0, 1, 1}, {1, 1, 2}, {0, 1, 1}},

};
const int vy[2][5][3] = {
    {{0, 0, 0}, {0, 1, 1}, {0, 1, 0}},
    {{0, 0, 0}, {-1, 0, -1}, {1, -1, 0}, {-1, 0, 0}, {1, 1, 2}}};

bool check(int *x, int *y) {
  vector<pair<int, int>> s(4);
  for (int i = 0; i < 4; i++)
    s[i] = {x[i], y[i]};
  sort(begin(s), end(s));
  s.erase(unique(begin(s), end(s)), end(s));
  if (s.size() == 3)
    return (false);

  bool mod = (s[0].first + s[0].second) % 2 != 0;
  for (int i = 0; i < 5; i++) {
    bool flag = true;
    for (int j = 1; j < s.size(); j++) {
      if (s[j].first - s[0].first != vx[mod][i][j - 1])
        flag = false;
      if (s[j].second - s[0].second != vy[mod][i][j - 1])
        flag = false;
    }
    if (flag)
      return (true);
  }
  return (false);
}

int main() {
  int N;
  int x[5000][4], y[5000][4];

  while (scanf("%d", &N), N) {

    int failed_count = 0;
    vector<pair<int, int>> enable[N], press;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 3; j++) {
        scanf("%d %d", &x[i][j], &y[i][j]);
      }
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < 3; k++) {
          x[i][3] = x[i][j] + dx[k];
          y[i][3] = y[i][j] + dy[(x[i][j] + y[i][j]) % 2 != 0][k];
          if (check(x[i], y[i]))
            enable[i].emplace_back(x[i][3], y[i][3]);
        }
      }

      sort(begin(enable[i]), end(enable[i]));
      enable[i].erase(unique(begin(enable[i]), end(enable[i])), end(enable[i]));
      for (auto &p : enable[i])
        press.emplace_back(p);
      if (enable[i].empty())
        failed_count++;
    }
    sort(begin(press), end(press));
    press.erase(unique(begin(press), end(press)), end(press));
    Bipartite_Matching flow(N + press.size());
    for (int i = 0; i < N; i++) {
      for (auto &p : enable[i]) {
        auto s = lower_bound(begin(press), end(press), p) - begin(press);
        flow.add_edge(i, N + s);
      }
    }
    int cnt = 0;

    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 3; j++) {
        auto q = make_pair(x[i][j], y[i][j]);
        auto p = lower_bound(begin(press), end(press), q);
        if (p == end(press))
          continue;
        if (*p == q)
          flow.kill(N + p - begin(press)), ++cnt;
      }
    }
    auto match = flow.bipartite_matching();
    if (match == N) {
      puts("Valid");
    } else {
      vector<int> ret;
      if (failed_count <= 1 && match >= N - 4) {
        for (int i = 0; i < N; i++) {
          for (int j = 0; j < 3; j++) {
            auto q = make_pair(x[i][j], y[i][j]);
            auto p = lower_bound(begin(press), end(press), q);
            if (p == end(press))
              continue;
            if (*p == q)
              match += flow.add(N + p - begin(press));
          }
          match += flow.kill(i);
          if (match == N - 1)
            ret.push_back(i);
          match += flow.add(i);
          for (int j = 0; j < 3; j++) {
            auto q = make_pair(x[i][j], y[i][j]);
            auto p = lower_bound(begin(press), end(press), q);
            if (p == end(press))
              continue;
            if (*p == q)
              match += flow.add(N + p - begin(press));
          }
        }
      }

      if (ret.empty()) {
        puts("Invalid");
      } else {
        puts("Remove");
        for (int k : ret)
          printf("%d\\n", k + 1);
      }
    }
  }
}