Problem p03321 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 700 + 117;
const int MM = 250000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("99e.in", "r", stdin);
  // freopen("99e.cpp.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int m, n;
int sq[NN][NN] = {};
vector<int> p[NN];
vector<int> v;
int has[2][NN] = {};
int col[NN] = {};
int dfs(int x, int c) {
  int res = c;
  col[x] = c;
  for (int i = 0; i < p[x].size(); ++i) {
    int cur = p[x][i];
    if (col[cur] == c) {
      return -2 * n;
    }
    if (!col[cur]) {
      int tp = dfs(cur, -c);
      if (tp < -n)
        return -2 * n;
      res += tp;
    }
  }
  return res;
}
int main() {
  open();
  n = read();
  m = read();
  for (int i = 1; i <= m; ++i) {
    int x = read(), y = read();
    sq[x][y] = 1;
    sq[y][x] = 1;
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (!sq[i][j] && i != j) {
        p[i].push_back(j);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (!col[i]) {
      int tp = dfs(i, 1);
      if (tp < -n) {
        printf("-1\n");
        return 0;
      }
      v.push_back(abs(tp));
    }
  }
  has[0][0] = 1;
  int now = 0;
  for (int pos = 0; pos < v.size(); ++pos) {
    now ^= 1;
    for (int i = n; i >= 0; --i) {
      if (has[now ^ 1][i]) {
        has[now][abs(i - v[pos])] = 1;
        has[now][i + v[pos]] = 1;
        has[now ^ 1][i] = 0;
      }
    }
  }
  int ans = n;
  for (int i = 0; i <= n; ++i) {
    if (has[now][i])
      ans = min(ans, i);
  }
  int aa = (ans + n) / 2;
  printf("%d\n", aa * (aa - 1) / 2 + (n - aa) * (n - aa - 1) / 2);
  close();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 700 + 117;
const int MM = 250000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("99e.in", "r", stdin);
  // freopen("99e.cpp.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int m, n;
int sq[NN][NN] = {};
vector<int> p[NN];
vector<int> v;
int has[2][NN] = {};
int col[NN] = {};
int dfs(int x, int c) {
  int res = c;
  col[x] = c;
  for (int i = 0; i < p[x].size(); ++i) {
    int cur = p[x][i];
    if (col[cur] == c) {
      return -2 * n;
    }
    if (!col[cur]) {
      int tp = dfs(cur, -c);
      if (tp < -n)
        return -2 * n;
      res += tp;
    }
  }
  return res;
}
int main() {
  // open();
  n = read();
  m = read();
  for (int i = 1; i <= m; ++i) {
    int x = read(), y = read();
    sq[x][y] = 1;
    sq[y][x] = 1;
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (!sq[i][j] && i != j) {
        p[i].push_back(j);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (!col[i]) {
      int tp = dfs(i, 1);
      if (tp < -n) {
        printf("-1\n");
        return 0;
      }
      v.push_back(abs(tp));
    }
  }
  has[0][0] = 1;
  int now = 0;
  for (int pos = 0; pos < v.size(); ++pos) {
    now ^= 1;
    for (int i = n; i >= 0; --i) {
      if (has[now ^ 1][i]) {
        has[now][abs(i - v[pos])] = 1;
        has[now][i + v[pos]] = 1;
        has[now ^ 1][i] = 0;
      }
    }
  }
  int ans = n;
  for (int i = 0; i <= n; ++i) {
    if (has[now][i])
      ans = min(ans, i);
  }
  int aa = (ans + n) / 2;
  printf("%d\n", aa * (aa - 1) / 2 + (n - aa) * (n - aa - 1) / 2);
  close();
  return 0;
}