Problem p03321 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <climits>
#include <iostream>
#include <map>
#include <utility>
#include <vector>

using namespace std;

vector<int> colors;
vector<vector<bool>> has_edge;
int diff;
vector<int> diffs;
int N, M;

bool dfs(int v, int c) {
  colors[v] = c;
  diff += c;
  for (int w = 0; w < N; w++) {
    if (!has_edge[v][w])
      continue;
    if (colors[w] == c)
      return false;
    if (colors[w] == 0 && !dfs(w, -c))
      return false;
  }
  return true;
}

vector<int> total_diffs(vector<int> diffs) {
  if (diffs.size() == 0)
    return {0};
  int last = diffs.back();
  diffs.pop_back();
  auto total_diffs_smaller = total_diffs(diffs);

  vector<int> total_diffs;
  for (auto total_diff : total_diffs_smaller) {
    total_diffs.emplace_back(total_diff + last);
    total_diffs.emplace_back(total_diff - last);
  }
  return total_diffs;
}

int main() {
  cin >> N >> M;

  has_edge.resize(N);
  for (int i = 0; i < N; i++) {
    has_edge[i].resize(N, true);
  }
  colors.resize(N, 0);

  for (int v = 0; v < N; v++) {
    has_edge[v][v] = false;
  }
  for (int i = 0; i < M; i++) {
    int A, B;
    cin >> A >> B;
    A--;
    B--;
    has_edge[A][B] = false;
    has_edge[B][A] = false;
  }

  for (int v = 0; v < N; v++) {
    if (colors[v] == 0) {
      diff = 0;
      if (!dfs(v, 1)) {
        cout << -1;
        return 0;
      }
      diffs.emplace_back(diff);
    }
  }
  int abs_total_diff_min = INT_MAX;
  for (auto total_diff : total_diffs(diffs)) {
    int t = abs(total_diff);
    if (abs_total_diff_min > t)
      abs_total_diff_min = t;
  }

  int bigger = (N + abs_total_diff_min) / 2;
  int smaller = (N - abs_total_diff_min) / 2;

  cout << (bigger * (bigger - 1) + smaller * (smaller - 1)) / 2;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <climits>
#include <iostream>
#include <map>
#include <utility>
#include <vector>

using namespace std;

vector<int> colors;
vector<vector<bool>> has_edge;
int diff;
vector<int> diffs;
int N, M;

bool dfs(int v, int c) {
  colors[v] = c;
  diff += c;
  for (int w = 0; w < N; w++) {
    if (!has_edge[v][w])
      continue;
    if (colors[w] == c)
      return false;
    if (colors[w] == 0 && !dfs(w, -c))
      return false;
  }
  return true;
}

vector<int> total_diffs(vector<int> diffs) {
  if (diffs.size() == 0)
    return {0};
  int last = diffs.back();
  diffs.pop_back();
  auto total_diffs_smaller = total_diffs(diffs);

  vector<int> total_diffs;
  for (auto total_diff : total_diffs_smaller) {
    total_diffs.emplace_back(total_diff + last);
    total_diffs.emplace_back(total_diff - last);
  }
  sort(total_diffs.begin(), total_diffs.end());
  total_diffs.erase(unique(total_diffs.begin(), total_diffs.end()),
                    total_diffs.end());
  return total_diffs;
}

int main() {
  cin >> N >> M;

  has_edge.resize(N);
  for (int i = 0; i < N; i++) {
    has_edge[i].resize(N, true);
  }
  colors.resize(N, 0);

  for (int v = 0; v < N; v++) {
    has_edge[v][v] = false;
  }
  for (int i = 0; i < M; i++) {
    int A, B;
    cin >> A >> B;
    A--;
    B--;
    has_edge[A][B] = false;
    has_edge[B][A] = false;
  }

  for (int v = 0; v < N; v++) {
    if (colors[v] == 0) {
      diff = 0;
      if (!dfs(v, 1)) {
        cout << -1;
        return 0;
      }
      diffs.emplace_back(diff);
    }
  }
  int abs_total_diff_min = INT_MAX;
  for (auto total_diff : total_diffs(diffs)) {
    int t = abs(total_diff);
    if (abs_total_diff_min > t)
      abs_total_diff_min = t;
  }

  int bigger = (N + abs_total_diff_min) / 2;
  int smaller = (N - abs_total_diff_min) / 2;

  cout << (bigger * (bigger - 1) + smaller * (smaller - 1)) / 2;
  return 0;
}