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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))
#define iter(v, ite) for (auto ite = (v).begin(); ite != (v).end(); ite++)
#define mimunum(v, x)                                                          \\
  distance((v).begin(), lower_bound((v).begin(), (v).end(), x))

lli n, m;
vector<int> vs[100005];

int gone[100005];

void dfs(int no, int &p, int &q, int c) {
  gone[no] = c;
  int tc = 3 - c;
  rep(i, vs[no].size()) {
    int to = vs[no][i];
    if (gone[to]) {
      if (gone[to] != tc) {
        puts("-1");
        exit(0);
      }
      continue;
    }
    dfs(to, p, q, tc);
  }
  if (c == 1)
    p++;
  else
    q++;
}

int tn[100005] = {};

int dpn = 1;
int dp[2][100005] = {};

int main(void) {
  scanf("%lld%lld", &n, &m);
  rep(i, m) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    vs[a].push_back(b);
    vs[b].push_back(a);
  }

  lli ds = 0;
  rep(i, n) {
    if (gone[i])
      continue;
    int p = 0, q = 0;
    dfs(i, p, q, 1);
    ds += abs(p - q);
    tn[abs(p - q)]++;
  }

  memset(dp, -1, sizeof(dp));
  dp[0][0] = 0;
  rep(i, n + 1) {
    if (!tn[i])
      continue;
    // printf("%d : %d\\n",i,tn[i]);
    rep(j, n + 3) {
      if (dp[1 - dpn][j] >= 0)
        dp[dpn][j] = tn[i];
      else if (j < i || dp[dpn][j - i] <= 0)
        ;
      else {
        dp[dpn][j] = dp[dpn][j - i] - 1;
      }
      // printf("dp[%d][%d] :: %d ,, %d
      // %d\\n",dpn,j,dp[dpn][j],dp[dpn-1][j],dp[dpn][j-i]);
    }
    dpn = 1 - dpn;
  }

  lli mt = IINF;
  rep(i, n + 3) {
    if (dp[1 - dpn][i] >= 0)
      mt = min(mt, abs(i - (ds - i)));
  }

  // printf("mt %lld\\n",mt);

  printf("%lld\\n", ((n + mt) / 2) * ((n + mt) / 2 - mt) - m);

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))
#define iter(v, ite) for (auto ite = (v).begin(); ite != (v).end(); ite++)
#define mimunum(v, x)                                                          \\
  distance((v).begin(), lower_bound((v).begin(), (v).end(), x))

lli n, m;
vector<int> vs[100005];

int gone[100005];

void dfs(int no, int &p, int &q, int c) {
  gone[no] = c;
  int tc = 3 - c;
  rep(i, vs[no].size()) {
    int to = vs[no][i];
    if (gone[to]) {
      if (gone[to] != tc) {
        puts("-1");
        exit(0);
      }
      continue;
    }
    dfs(to, p, q, tc);
  }
  if (c == 1)
    p++;
  else
    q++;
}

int tn[100005] = {};

int dpn = 1;
int dp[1005][100005] = {};

int main(void) {
  scanf("%lld%lld", &n, &m);
  rep(i, m) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    vs[a].push_back(b);
    vs[b].push_back(a);
  }

  lli ds = 0;
  rep(i, n) {
    if (gone[i])
      continue;
    int p = 0, q = 0;
    dfs(i, p, q, 1);
    ds += abs(p - q);
    tn[abs(p - q)]++;
  }

  memset(dp, -1, sizeof(dp));
  dp[0][0] = 0;
  rep(i, n + 1) {
    if (!tn[i])
      continue;
    // printf("%d : %d\\n",i,tn[i]);
    rep(j, n + 3) {
      if (dp[dpn - 1][j] >= 0)
        dp[dpn][j] = tn[i];
      else if (j < i || dp[dpn][j - i] <= 0)
        ;
      else {
        dp[dpn][j] = dp[dpn][j - i] - 1;
      }
      // printf("dp[%d][%d] :: %d ,, %d
      // %d\\n",dpn,j,dp[dpn][j],dp[dpn-1][j],dp[dpn][j-i]);
    }
    dpn++;
  }

  lli mt = IINF;
  rep(i, n + 3) {
    if (dp[dpn - 1][i] >= 0)
      mt = min(mt, abs(i - (ds - i)));
  }

  // printf("mt %lld\\n",mt);

  printf("%lld\\n", ((n + mt) / 2) * ((n + mt) / 2 - mt) - m);

  return 0;
}