Problem p03321 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < n; i++)
#define mkp(a, b) make_pair(a, b)
const long long mod = 1000000007;
const long long inf = 1ll << 61;
typedef pair<int, int> P;
typedef pair<int, P> PP;
struct edge {
  int to;
  int to2;
  int cost;
};
struct p3 {
  int a;
  int b;
  int c;
};

int a[50000], b[50000];
int grf[702][702];
vector<int> G[702];
int color[702];
int dp[2][702][702];
int R[702], B[702], ed[702];

int par[705], rnk[705], heavy[705];
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 0;
    heavy[i] = 1;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (heavy[x] < heavy[y])
    swap(x, y);
  par[y] = x;
  heavy[x] += heavy[y];
}
void initdp(int a, int n) { rep(i, n) rep(j, n) dp[a][i][j] = -1; }
void dispdp(int a, int n) {
  rep(i, n) {
    rep(j, n) {
      if (j)
        cout << ' ';
      cout << dp[a][i][j];
    }
    cout << endl;
  }
  cout << endl;
}
bool dfs(int v, int c) {
  color[v] = c;
  rep(i, G[v].size()) {
    if (color[G[v][i]] == c)
      return false;
    if (color[G[v][i]] == 0 && !dfs(G[v][i], -c))
      return false;
  }
  return true;
}

signed main() {
  int n, m;
  cin >> n >> m;
  init(n);

  rep(i, m) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
    grf[a[i]][b[i]]++;
    grf[b[i]][a[i]]++;
  }
  rep(i, n) grf[i][i]++;
  rep(i, n) {
    rep(j, n) {
      if (!grf[i][j]) {
        G[i].push_back(j);
        unite(i, j);
      }
    }
  }
  rep(i, n) {
    if (!color[i]) {
      if (!dfs(i, 1)) {
        puts("-1");
        return 0;
      }
    }
  }
  rep(i, n) {
    if (color[i] == 1) {
      R[find(i)]++;
    } else
      B[find(i)]++;
  }
  rep(i, n) { ed[find(i)] += G[i].size(); }
  rep(i, n) ed[i] /= 2;
  vector<p3> V;
  rep(i, n) {
    if (R[i] || B[i]) {
      V.push_back({R[i], B[i], R[i] * B[i] - ed[i]});
    }
  }
  initdp(0, n + 1);
  initdp(1, n + 1);
  dp[0][0][0] = 0;
  rep(k, V.size()) {
    rep(i, n + 1) {
      rep(j, n + 1) {
        if (dp[k & 1][i][j] == -1)
          continue;
        int na = V[k].a, nb = V[k].b;
        int ni = i + na, nj = j + nb, mi = i + nb, mj = j + na;
        dp[(k + 1) & 1][ni][nj] =
            max(dp[(k + 1) & 1][ni][nj],
                dp[k & 1][i][j] + V[k].c + i * nb + j * na);
        dp[(k + 1) & 1][mi][mj] =
            max(dp[(k + 1) & 1][mi][mj],
                dp[k & 1][i][j] + V[k].c + i * na + j * nb);
      }
    }
    // dispdp((k + 1) & 1, n + 1);
    initdp(k & 1, n + 1);
  }
  int res = 0;
  rep(i, n + 1) { res = max(res, dp[1 & V.size()][i][n - i]); }

  cout << m - res << endl;
}

Fixed submission:
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < n; i++)
#define mkp(a, b) make_pair(a, b)
const long long mod = 1000000007;
const long long inf = 1ll << 61;
typedef pair<int, int> P;
typedef pair<int, P> PP;
struct edge {
  int to;
  int to2;
  int cost;
};
struct p3 {
  int a;
  int b;
  int c;
};

int a[500000], b[500000];
int grf[702][702];
vector<int> G[702];
int color[702];
int dp[2][702][702];
int R[702], B[702], ed[702];

int par[705], rnk[705], heavy[705];
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 0;
    heavy[i] = 1;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (heavy[x] < heavy[y])
    swap(x, y);
  par[y] = x;
  heavy[x] += heavy[y];
}
void initdp(int a, int n) { rep(i, n) rep(j, n) dp[a][i][j] = -1; }
void dispdp(int a, int n) {
  rep(i, n) {
    rep(j, n) {
      if (j)
        cout << ' ';
      cout << dp[a][i][j];
    }
    cout << endl;
  }
  cout << endl;
}
bool dfs(int v, int c) {
  color[v] = c;
  rep(i, G[v].size()) {
    if (color[G[v][i]] == c)
      return false;
    if (color[G[v][i]] == 0 && !dfs(G[v][i], -c))
      return false;
  }
  return true;
}

signed main() {
  int n, m;
  cin >> n >> m;
  init(n);

  rep(i, m) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
    grf[a[i]][b[i]]++;
    grf[b[i]][a[i]]++;
  }
  rep(i, n) grf[i][i]++;
  rep(i, n) {
    rep(j, n) {
      if (!grf[i][j]) {
        G[i].push_back(j);
        unite(i, j);
      }
    }
  }
  rep(i, n) {
    if (!color[i]) {
      if (!dfs(i, 1)) {
        puts("-1");
        return 0;
      }
    }
  }
  rep(i, n) {
    if (color[i] == 1) {
      R[find(i)]++;
    } else
      B[find(i)]++;
  }
  rep(i, n) { ed[find(i)] += G[i].size(); }
  rep(i, n) ed[i] /= 2;
  vector<p3> V;
  rep(i, n) {
    if (R[i] || B[i]) {
      V.push_back({R[i], B[i], R[i] * B[i] - ed[i]});
    }
  }
  initdp(0, n + 1);
  initdp(1, n + 1);
  dp[0][0][0] = 0;
  rep(k, V.size()) {
    rep(i, n + 1) {
      rep(j, n + 1) {
        if (dp[k & 1][i][j] == -1)
          continue;
        int na = V[k].a, nb = V[k].b;
        int ni = i + na, nj = j + nb, mi = i + nb, mj = j + na;
        dp[(k + 1) & 1][ni][nj] =
            max(dp[(k + 1) & 1][ni][nj],
                dp[k & 1][i][j] + V[k].c + i * nb + j * na);
        dp[(k + 1) & 1][mi][mj] =
            max(dp[(k + 1) & 1][mi][mj],
                dp[k & 1][i][j] + V[k].c + i * na + j * nb);
      }
    }
    // dispdp((k + 1) & 1, n + 1);
    initdp(k & 1, n + 1);
  }
  int res = 0;
  rep(i, n + 1) { res = max(res, dp[1 & V.size()][i][n - i]); }

  cout << m - res << endl;
}