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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb push_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;

template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

struct edge {
  int to, cap, cost, rev;
  edge(int a, int b, int c, int d) : to(a), cap(b), cost(c), rev(d) {}
};
const int MAX_V = 6010;
const ll INF = 1001001001001ll;
int V;
vector<edge> G[MAX_V];
ll h[MAX_V];
ll dist[MAX_V];
bool used[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost) {
  G[from].push_back(edge(to, cap, cost, G[to].size()));
  G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}

int min_cost_flow(int s, int t, int f) {
  vint deg(MAX_V);
  rep(i, MAX_V) for (auto &e : G[i]) if (e.cap) deg[e.to]++;

  fill_n(h, MAX_V, INF);
  queue<int> que;
  rep(i, MAX_V) if (deg[i] == 0) {
    if (i == s)
      h[i] = 0;
    que.push(i);
  }
  while (que.size()) {
    int v = que.front();
    que.pop();
    for (auto &e : G[v])
      if (e.cap) {
        chmin(h[e.to], h[v] + e.cost);
        if (--deg[e.to] == 0)
          que.push(e.to);
      }
  }

  int res = 0;
  while (f > 0) {
    fill_n(dist, MAX_V, INF);
    dist[s] = 0;
    memset(used, 0, sizeof(used));
    while (true) {
      int v = -1;
      for (int u = 0; u < MAX_V; u++)
        if (!used[u] && (v == -1 || dist[v] > dist[u]))
          v = u;
      if (v == -1)
        break;
      used[v] = true;
      for (int i = 0; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap == 0 || dist[e.to] <= dist[v] + e.cost + h[v] - h[e.to])
          continue;
        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
        prevv[e.to] = v;
        preve[e.to] = i;
      }
    }
    if (dist[t] == INF)
      return -1;
    int d = f;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    for (int v = 0; v < MAX_V; v++)
      h[v] += dist[v];

    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = prevv[v]) {
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

signed main() {
  int n, v, xl, xr;

  cin >> n >> v >> xl >> xr;
  vint x(n), t(n), p(n);

  rep(i, n) { cin >> x[i] >> t[i] >> p[i]; }
  int src = MAX_V - 2, snk = MAX_V - 1, l = MAX_V - 3, r = MAX_V - 4;

  rep(i, n) {
    add_edge(i * 2, i * 2 + 1, 1, -p[i]);
    add_edge(i * 2 + 1, snk, 1, 0);

    if (abs(xl - x[i]) <= t[i] * v)
      add_edge(l, i * 2, 1, 0);
    if (abs(xr - x[i]) <= t[i] * v)
      add_edge(r, i * 2, 1, 0);
  }

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (i != j) {
        if (abs(x[i] - x[j]) <= v * (t[j] - t[i])) {
          add_edge(i * 2 + 1, j * 2, 1, 0);
        }
      }
  add_edge(src, snk, 2, 0);
  add_edge(src, l, 1, 0);
  add_edge(src, r, 1, 0);

  cout << -min_cost_flow(src, snk, 2) << endl;
  return 0;
}

Error: MLE

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 pb push_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;

template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

struct edge {
  int to, cap, cost, rev;
  edge(int a, int b, int c, int d) : to(a), cap(b), cost(c), rev(d) {}
};
const int MAX_V = 6010;
const int INF = 1001001001001;
int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
bool used[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost) {
  G[from].push_back(edge(to, cap, cost, G[to].size()));
  G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}

int min_cost_flow(int s, int t, int f) {
  vint deg(MAX_V);
  rep(i, MAX_V) for (auto &e : G[i]) if (e.cap) deg[e.to]++;

  fill_n(h, MAX_V, INF);
  queue<int> que;
  rep(i, MAX_V) if (deg[i] == 0) {
    if (i == s)
      h[i] = 0;
    que.push(i);
  }
  while (que.size()) {
    int v = que.front();
    que.pop();
    for (auto &e : G[v])
      if (e.cap) {
        chmin(h[e.to], h[v] + e.cost);
        if (--deg[e.to] == 0)
          que.push(e.to);
      }
  }

  int res = 0;
  while (f > 0) {
    fill_n(dist, MAX_V, INF);
    dist[s] = 0;
    memset(used, 0, sizeof(used));
    while (true) {
      int v = -1;
      for (int u = 0; u < MAX_V; u++)
        if (!used[u] && (v == -1 || dist[v] > dist[u]))
          v = u;
      if (v == -1)
        break;
      used[v] = true;
      for (int i = 0; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap == 0 || dist[e.to] <= dist[v] + e.cost + h[v] - h[e.to])
          continue;
        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
        prevv[e.to] = v;
        preve[e.to] = i;
      }
    }
    if (dist[t] == INF)
      return -1;
    int d = f;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    for (int v = 0; v < MAX_V; v++)
      if (dist[v] != INF)
        h[v] += dist[v];

    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = prevv[v]) {
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

signed main() {
  int n, v, xl, xr;

  cin >> n >> v >> xl >> xr;
  vint x(n), t(n), p(n);

  rep(i, n) { cin >> x[i] >> t[i] >> p[i]; }
  int src = MAX_V - 2, snk = MAX_V - 1, l = MAX_V - 3, r = MAX_V - 4;

  rep(i, n) {
    add_edge(i * 2, i * 2 + 1, 1, -p[i]);
    add_edge(i * 2 + 1, snk, 1, 0);

    if (abs(xl - x[i]) <= t[i] * v)
      add_edge(l, i * 2, 1, 0);
    if (abs(xr - x[i]) <= t[i] * v)
      add_edge(r, i * 2, 1, 0);
  }

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (i != j) {
        if (abs(x[i] - x[j]) <= v * (t[j] - t[i])) {
          add_edge(i * 2 + 1, j * 2, 1, 0);
        }
      }
  add_edge(src, snk, 2, 0);
  add_edge(src, l, 1, 0);
  add_edge(src, r, 1, 0);

  cout << -min_cost_flow(src, snk, 2) << endl;
  return 0;
}