Problem p03642 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> PP;

// This code performs maximum bipartite matching.
//
// Running time: O(|E| |V|) -- often much faster in practice
//
//   INPUT: w[i][j] = edge between row node i and column node j
//   OUTPUT: mr[i] = assignment for row node i, -1 if unassigned
//           mc[j] = assignment for column node j, -1 if unassigned
//           function returns number of matches made

typedef vector<int> VI;
typedef vector<VI> VVI;

bool FindMatch(int i, const VVI &w, VI &mr, VI &mc, VI &seen) {
  for (int j = 0; j < w[i].size(); j++) {
    if (w[i][j] && !seen[j]) {
      seen[j] = true;
      if (mc[j] < 0 || FindMatch(mc[j], w, mr, mc, seen)) {
        mr[i] = j;
        mc[j] = i;
        return true;
      }
    }
  }
  return false;
}

int BipartiteMatching(const VVI &w) {
  VI mr = VI(w.size(), -1);
  VI mc = VI(w[0].size(), -1);

  int ct = 0;
  for (int i = 0; i < w.size(); i++) {
    VI seen(w[0].size());
    if (FindMatch(i, w, mr, mc, seen))
      ct++;
  }
  return ct;
}

set<int> P;
const int B = 1E7 + 10;
bool sieve[B];

int main() {
  ios::sync_with_stdio(false);
  int N;
  cin >> N;
  set<int> M;
  for (int i = 0; i < N; i++) {
    int n;
    cin >> n;
    M.insert(n);
  }
  memset(sieve, 0, sizeof(sieve));
  for (int i = 2; i < B; i++) {
    if (sieve[i] == 0) {
      for (int j = i; j < B; j += i)
        sieve[j] = 1;
      if (i % 2)
        P.insert(i);
    }
  }
  set<int> Q;
  for (auto m : M) {
    if (M.count(m - 1) == 0)
      Q.insert(m - 1);
    if (M.count(m + 1) == 0)
      Q.insert(m);
  }
  vector<int> R;
  for (auto m : Q)
    R.push_back(m);
  int sz = R.size();
  vector<int> o, e;
  for (int i = 0; i < sz; i++) {
    if (R[i] % 2)
      o.push_back(R[i]);
    else
      e.push_back(R[i]);
  }
  vector<int> tmp(e.size(), 0);
  vector<vector<int>> T(o.size(), tmp);
  for (int i = 0; i < o.size(); i++) {
    for (int j = 0; j < e.size(); j++) {
      if (P.count(abs(o[i] - e[j])))
        T[i][j] = 1;
    }
  }
  int mc = BipartiteMatching(T);
  int oo = o.size() - mc;
  int ee = e.size() - mc;
  cout << mc + 2 * (oo / 2 + ee / 2) + 3 * (oo % 2) << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> PP;

// This code performs maximum bipartite matching.
//
// Running time: O(|E| |V|) -- often much faster in practice
//
//   INPUT: w[i][j] = edge between row node i and column node j
//   OUTPUT: mr[i] = assignment for row node i, -1 if unassigned
//           mc[j] = assignment for column node j, -1 if unassigned
//           function returns number of matches made

typedef vector<int> VI;
typedef vector<VI> VVI;

bool FindMatch(int i, const VVI &w, VI &mr, VI &mc, VI &seen) {
  for (int j = 0; j < w[i].size(); j++) {
    if (w[i][j] && !seen[j]) {
      seen[j] = true;
      if (mc[j] < 0 || FindMatch(mc[j], w, mr, mc, seen)) {
        mr[i] = j;
        mc[j] = i;
        return true;
      }
    }
  }
  return false;
}

int BipartiteMatching(const VVI &w) {
  VI mr = VI(w.size(), -1);
  VI mc = VI(w[0].size(), -1);

  int ct = 0;
  for (int i = 0; i < w.size(); i++) {
    VI seen(w[0].size());
    if (FindMatch(i, w, mr, mc, seen))
      ct++;
  }
  return ct;
}

set<int> P;
const int B = 1E7 + 10;
bool sieve[B];

int main() {
  ios::sync_with_stdio(false);
  int N;
  cin >> N;
  set<int> M;
  for (int i = 0; i < N; i++) {
    int n;
    cin >> n;
    M.insert(n);
  }
  memset(sieve, 0, sizeof(sieve));
  for (int i = 2; i < B; i++) {
    if (sieve[i] == 0) {
      for (int j = i; j < B; j += i)
        sieve[j] = 1;
      if (i % 2)
        P.insert(i);
    }
  }
  set<int> Q;
  for (auto m : M) {
    if (M.count(m - 1) == 0)
      Q.insert(m - 1);
    if (M.count(m + 1) == 0)
      Q.insert(m);
  }
  vector<int> R;
  for (auto m : Q)
    R.push_back(m);
  int sz = R.size();
  vector<int> o, e;
  for (int i = 0; i < sz; i++) {
    if (R[i] % 2)
      o.push_back(R[i]);
    else
      e.push_back(R[i]);
  }
  vector<int> tmp(e.size(), 0);
  vector<vector<int>> T(o.size(), tmp);
  for (int i = 0; i < o.size(); i++) {
    for (int j = 0; j < e.size(); j++) {
      if (P.count(abs(o[i] - e[j])))
        T[i][j] = 1;
    }
  }
  int mc = 0;
  if (o.size() > 0 && e.size() > 0)
    mc = BipartiteMatching(T);
  int oo = o.size() - mc;
  int ee = e.size() - mc;
  cout << mc + 2 * (oo / 2 + ee / 2) + 3 * (oo % 2) << endl;
  return 0;
}