Problem p03642 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define file(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout)

inline int read() {
  int data = 0, w = 1;
  char ch = getchar();
  while (ch != '-' && (ch < '0' || ch > '9'))
    ch = getchar();
  if (ch == '-')
    w = -1, ch = getchar();
  while (ch >= '0' && ch <= '9')
    data = data * 10 + (ch ^ 48), ch = getchar();
  return data * w;
}

const int N(105), LIM(1e7), M(LIM + 10), INF(0x3f3f3f3f);
struct edge {
  int next, to, cap;
} e[N * N * 2];
int n, a[M], head[N], e_num = -1, cnt, L[N], R[N], cntl, cntr;
int lev[N], cur[N], S, T, not_prime[M], prime[M];
inline int Abs(int x) { return x < 0 ? -x : x; }
inline void Add(int from, int to, int cap) {
  e[++e_num] = (edge){head[from], to, cap}, head[from] = e_num;
  e[++e_num] = (edge){head[to], from, 0}, head[to] = e_num;
}

void Init() {
  not_prime[1] = 1;
  for (int i = 2; i <= LIM; i++) {
    if (!not_prime[i])
      prime[++cnt] = i;
    for (int j = 1; j <= cnt && 1ll * i * prime[j] <= LIM; j++) {
      not_prime[i * prime[j]] = 1;
      if (!(i % prime[j]))
        break;
    }
  }
}

int bfs() {
  std::queue<int> Q;
  Q.push(S);
  memset(lev, 0, (T + 1) << 2), lev[S] = 1;
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (int i = head[x]; ~i; i = e[i].next) {
      int to = e[i].to;
      if (lev[to] || !e[i].cap)
        continue;
      lev[to] = lev[x] + 1, Q.push(to);
    }
  }
  return lev[T];
}

int dfs(int x, int f) {
  if (x == T || !f)
    return f;
  int ans = 0, cap;
  for (int &i = cur[x]; ~i; i = e[i].next) {
    int to = e[i].to;
    if (lev[to] == lev[x] + 1 && e[i].cap) {
      cap = dfs(to, std::min(f - ans, e[i].cap));
      e[i].cap -= cap, e[i ^ 1].cap += cap, ans += cap;
      if (ans == f)
        break;
    }
  }
  if (!ans)
    lev[x] = 0;
  return ans;
}

int Dinic() {
  int ans = 0;
  while (bfs())
    memcpy(cur, head, (T + 1) << 2), ans += dfs(S, INF);
  return ans;
}

int main() {
  Init(), n = read(), memset(head, -1, sizeof head);
  for (int i = 1; i <= n; i++)
    ++a[read()];
  for (int i = 0; i <= LIM; i++)
    if (a[i] != a[i + 1])
      (i & 1) ? R[++cntr] = i + 1 : L[++cntl] = i + 1;
  S = 0, T = cntl + cntr + 1;
  for (int i = 1; i <= cntl; i++)
    Add(S, i, 1);
  for (int i = 1; i <= cntr; i++)
    Add(i + cntl, T, 1);
  for (int i = 1; i <= cntl; i++)
    for (int j = 1; j <= cntr; j++)
      if (!not_prime[Abs(L[i] - R[j])])
        Add(i, j + cntl, 1);
  int f = Dinic(), ans = f, tl = cntl - f, tr = cntr - f;
  ans += tl - (tl & 1) + tr - (tr & 1), ans += 3 * (tl & 1);
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define file(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout)

inline int read() {
  int data = 0, w = 1;
  char ch = getchar();
  while (ch != '-' && (ch < '0' || ch > '9'))
    ch = getchar();
  if (ch == '-')
    w = -1, ch = getchar();
  while (ch >= '0' && ch <= '9')
    data = data * 10 + (ch ^ 48), ch = getchar();
  return data * w;
}

const int N(205), LIM(1e7), M(LIM + 10), INF(0x3f3f3f3f);
struct edge {
  int next, to, cap;
} e[N * N * 2];
int n, a[M], head[N], e_num = -1, cnt, L[N], R[N], cntl, cntr;
int lev[N], cur[N], S, T, not_prime[M], prime[M];
inline int Abs(int x) { return x < 0 ? -x : x; }
inline void Add(int from, int to, int cap) {
  e[++e_num] = (edge){head[from], to, cap}, head[from] = e_num;
  e[++e_num] = (edge){head[to], from, 0}, head[to] = e_num;
}

void Init() {
  not_prime[1] = 1;
  for (int i = 2; i <= LIM; i++) {
    if (!not_prime[i])
      prime[++cnt] = i;
    for (int j = 1; j <= cnt && 1ll * i * prime[j] <= LIM; j++) {
      not_prime[i * prime[j]] = 1;
      if (!(i % prime[j]))
        break;
    }
  }
}

int bfs() {
  std::queue<int> Q;
  Q.push(S);
  memset(lev, 0, (T + 1) << 2), lev[S] = 1;
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (int i = head[x]; ~i; i = e[i].next) {
      int to = e[i].to;
      if (lev[to] || !e[i].cap)
        continue;
      lev[to] = lev[x] + 1, Q.push(to);
    }
  }
  return lev[T];
}

int dfs(int x, int f) {
  if (x == T || !f)
    return f;
  int ans = 0, cap;
  for (int &i = cur[x]; ~i; i = e[i].next) {
    int to = e[i].to;
    if (lev[to] == lev[x] + 1 && e[i].cap) {
      cap = dfs(to, std::min(f - ans, e[i].cap));
      e[i].cap -= cap, e[i ^ 1].cap += cap, ans += cap;
      if (ans == f)
        break;
    }
  }
  if (!ans)
    lev[x] = 0;
  return ans;
}

int Dinic() {
  int ans = 0;
  while (bfs())
    memcpy(cur, head, (T + 1) << 2), ans += dfs(S, INF);
  return ans;
}

int main() {
  Init(), n = read(), memset(head, -1, sizeof head);
  for (int i = 1; i <= n; i++)
    ++a[read()];
  for (int i = 0; i <= LIM; i++)
    if (a[i] != a[i + 1])
      (i & 1) ? R[++cntr] = i + 1 : L[++cntl] = i + 1;
  S = 0, T = cntl + cntr + 1;
  for (int i = 1; i <= cntl; i++)
    Add(S, i, 1);
  for (int i = 1; i <= cntr; i++)
    Add(i + cntl, T, 1);
  for (int i = 1; i <= cntl; i++)
    for (int j = 1; j <= cntr; j++)
      if (!not_prime[Abs(L[i] - R[j])])
        Add(i, j + cntl, 1);
  int f = Dinic(), ans = f, tl = cntl - f, tr = cntr - f;
  ans += tl - (tl & 1) + tr - (tr & 1), ans += 3 * (tl & 1);
  printf("%d\n", ans);
  return 0;
}