Problem p03321 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<int, lint> pil;
typedef pair<lint, lint> pll;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> T div_floor(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T> T div_ceil(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1e9 + 7;
constexpr lint INF = mod * mod;
constexpr int MAX = 710;

int n, m;
bool G[MAX][MAX];
vector<int> cG[MAX];
int mark[MAX];
vector<int> t;

bool dfs(int v, int pv, int col) {
  if (mark[v] >= 0)
    return mark[v] == col;
  mark[v] = col;
  ++t[col];
  for (int nv : cG[v])
    if (nv != pv) {
      if (!dfs(nv, v, col ^ 1))
        return false;
    }
  return true;
}

int main() {
  scanf("%d%d", &n, &m);
  rep(i, n) rep(j, m) G[i][j] = false;
  rep(i, m) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    G[a][b] = G[b][a] = true;
  }
  rep(i, n) For(j, i + 1, n) if (!G[i][j]) {
    cG[i].push_back(j);
    cG[j].push_back(i);
  }

  vector<pii> num;
  rep(i, n) mark[i] = -1;
  rep(i, n) if (mark[i] < 0) {
    t = {0, 0};
    if (!dfs(i, -1, 0)) {
      puts("-1");
      return 0;
    }
    num.emplace_back(t[0], t[1]);
  }

  int K = num.size();
  bool dp[K + 1][n + 1];
  rep(i, K + 1) rep(j, n + 1) dp[i][j] = false;
  dp[0][0] = true;
  rep(i, K) rep(j, n + 1) if (dp[i][j]) {
    dp[i + 1][j + num[i].fi] = true;
    dp[i + 1][j + num[i].se] = true;
  }
  int ans = m;
  rep(j, n + 1) if (dp[K][j]) {
    chmin(ans, j * (j - 1) / 2 + (n - j) * (n - j - 1) / 2);
  }
  printf("%d\n", ans);
}

Fixed submission:
#include <bits/stdc++.h>
#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<int, lint> pil;
typedef pair<lint, lint> pll;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> T div_floor(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T> T div_ceil(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1e9 + 7;
constexpr lint INF = mod * mod;
constexpr int MAX = 710;

int n, m;
bool G[MAX][MAX];
vector<int> cG[MAX];
int mark[MAX];
vector<int> t;

bool dfs(int v, int pv, int col) {
  if (mark[v] >= 0)
    return mark[v] == col;
  mark[v] = col;
  ++t[col];
  for (int nv : cG[v])
    if (nv != pv) {
      if (!dfs(nv, v, col ^ 1))
        return false;
    }
  return true;
}

int main() {
  scanf("%d%d", &n, &m);
  rep(i, n) rep(j, n) G[i][j] = false;
  rep(i, m) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    G[a][b] = G[b][a] = true;
  }
  rep(i, n) For(j, i + 1, n) if (!G[i][j]) {
    cG[i].push_back(j);
    cG[j].push_back(i);
  }

  vector<pii> num;
  rep(i, n) mark[i] = -1;
  rep(i, n) if (mark[i] < 0) {
    t = {0, 0};
    if (!dfs(i, -1, 0)) {
      puts("-1");
      return 0;
    }
    num.emplace_back(t[0], t[1]);
  }

  int K = num.size();
  bool dp[K + 1][n + 1];
  rep(i, K + 1) rep(j, n + 1) dp[i][j] = false;
  dp[0][0] = true;
  rep(i, K) rep(j, n + 1) if (dp[i][j]) {
    dp[i + 1][j + num[i].fi] = true;
    dp[i + 1][j + num[i].se] = true;
  }
  int ans = m;
  rep(j, n + 1) if (dp[K][j]) {
    chmin(ans, j * (j - 1) / 2 + (n - j) * (n - j - 1) / 2);
  }
  printf("%d\n", ans);
}