Problem p01487 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define FOR(i, k, n) for (int64_t i = (k); i < (int64_t)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;
using Graph = vector<vector<int>>;

void add_edge(Graph &g, int a, int b) {
  g[a].push_back(b);
  g[b].push_back(a);
}

bool dfs(const Graph &g, vector<int> &vis, int i) {
  for (int j : g[i]) {
    if (vis[j] == -1) {
      vis[j] = vis[i] ^ 1;
      if (!dfs(g, vis, j))
        return false;
    } else if (vis[j] == vis[i]) {
      return false;
    }
  }
  return true;
}

int main() {
  int64_t v, e;
  cin >> v >> e;
  Graph g(v);
  REP(i, e) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    add_edge(g, a, b);
  }
  vector<int> vis(v, -1);
  bool ok = true;
  int cnt = 0;
  REP(i, v) {
    if (vis[i] == -1) {
      vis[i] = 2 * cnt;
      if (!dfs(g, vis, i)) {
        ok = false;
      }
      ++cnt;
    }
  }
  if (!ok) {
    cout << -1 << endl;
    return 0;
  }
  vector<int> ary(cnt, 0);
  REP(i, v) {
    if ((vis[i] % 2) == 0) {
      ++ary[vis[i] / 2];
    } else {
      --ary[vis[i] / 2];
    }
  }
  REP(i, cnt) ary[i] = abs(ary[i]);
  int64_t sum = 0;
  REP(i, cnt) sum += ary[i];
  bitset<100001> dp;
  dp[0] = true;
  REP(i, cnt) {
    bitset<100001> tmp = dp;
    tmp |= dp << ary[i];
    swap(tmp, dp);
  }
  int64_t mx = 0;
  REP(i, sum + 1) {
    if (dp[i]) {
      int64_t k = 2 * i - sum;
      mx = max(mx, (v - k) / 2 * (v + k) / 2 - e);
    }
  }
  cout << mx << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define FOR(i, k, n) for (int i = (k); i < int(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;
constexpr int INF = 1000000000;

bool dfs(vector<vector<int>> &g, int i, vector<int> &clr, int cnt,
         int odd = 1) {
  clr[i] = 2 * cnt + odd;
  bool ok = true;
  for (int nx : g[i]) {
    if (clr[nx] == clr[i])
      return false;
    if (clr[nx] != -1)
      continue;
    ok = ok && dfs(g, nx, clr, cnt, 1 - odd);
  }
  return ok;
}

int main() {
  int v, e;
  cin >> v >> e;
  vector<vector<int>> g(v);
  REP(i, e) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  vector<int> clr(v, -1);
  bool ok = true;
  int cnt = 0;
  REP(i, v) {
    if (clr[i] == -1) {
      ok = ok && dfs(g, i, clr, cnt++);
    }
  }
  if (!ok) {
    cout << -1 << endl;
    return 0;
  }
  vector<int> sum(2 * cnt);
  REP(i, v) { ++sum[clr[i]]; }
  REP(i, cnt) { sum[2 * i] -= sum[2 * i + 1]; }
  vector<int> df2(cnt);
  REP(i, cnt) { df2[i] = 2 * abs(sum[2 * i]); }
  sort(ALL(df2));
  int ofs = 0;
  REP(i, cnt) if (!df2[i])++ ofs;
  int ofs2 = ofs;
  REP(i, cnt) if (df2[i] == 1)++ ofs2;
  int twice = 0;
  REP(i, cnt) twice += df2[i];
  vector<bool> dp(twice + 1);
  dp[0] = 1;
  REP(i, cnt - ofs2) {
    auto tmp = dp;
    REP(j, twice - df2[i + ofs2] + 1) {
      if (dp[j])
        tmp[j + df2[i + ofs2]] = true;
    }
    swap(tmp, dp);
  }
  int mn = INF;
  REP(i, twice + 1) {
    if (dp[i])
      mn = min(mn, abs(i - twice / 2));
  }
  int64_t smaller = v / 2 - mn / 2 + ofs2 - ofs;
  if (smaller > v / 2)
    smaller = v / 2;
  int64_t larger = v - smaller;
  int64_t m = smaller * larger;
  cout << (m - e) << endl;
  return 0;
}