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

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = (int)(a)-1; i >= (int)(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))

// #define DEBUG

#ifdef DEBUG
#define dump(...) fprintf(stderr, __VA_ARGS__)
#else
#define dump(...)
#endif

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;
using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;

const double EPS = 1e-10;
const double PI = acos(-1.0);
const ll mod = 1000000007LL;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

ll extgcd(ll a, ll b, ll &x, ll &y) {
  x = 1, y = 0;
  ll g = a;
  if (b != 0)
    g = extgcd(b, a % b, y, x), y -= a / b * x;
  return g;
}
ll ADD(const ll &a, const ll &b, const ll &mod) { return (a + b) % mod; }
ll SUB(const ll &a, const ll &b, const ll &mod) { return (a - b + mod) % mod; }
ll MUL(const ll &a, const ll &b, const ll &mod) { return (1LL * a * b) % mod; }
ll DIV(const ll &a, const ll &b, const ll &mod) {
  ll x, y;
  extgcd(b, mod, x, y);
  return MUL(a, (x + mod) % mod, mod);
}

random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dice(1, 6);
uniform_real_distribution<double> score(0.0, 10.0);

using W = int;
using edge = struct {
  int to, rev;
  W cap, flow, cost;
};
using G = vector<vector<edge>>;

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

W primal_dual(G &graph, int s, int t, int f) {
  const W inf = 1 << 30;
  W res = 0;
  while (f) {
    int n = graph.size(), update;
    vector<W> dist(n, inf);
    vector<int> pv(n, 0), pe(n, 0);
    dist[s] = 0;

    rep(loop, n) {
      update = false;
      rep(v, n) rep(i, graph[v].size()) {
        edge &e = graph[v][i];
        if (e.cap > e.flow and chmin(dist[e.to], dist[v] + e.cost)) {
          pv[e.to] = v, pe[e.to] = i;
          update = true;
        }
      }
      if (!update)
        break;
    }

    if (dist[t] == inf)
      return -1;

    W d = f;

    for (int v = t; v != s; v = pv[v]) {
      chmin(d, graph[pv[v]][pe[v]].cap - graph[pv[v]][pe[v]].flow);
    }

    f -= d, res += d * dist[t];

    for (int v = t; v != s; v = pv[v]) {
      edge &e = graph[pv[v]][pe[v]];
      e.flow += d;
      graph[v][e.rev].flow -= d;
    }
  }
  return res;
}
W min_cost_flow(G &graph, int s, int t, int f) {
  const W inf = 1 << 30;
  W res = 0;

  while (f) {
    int n = graph.size();
    vi h(n);
    vi prevv(n), preve(n);

    using P = pair<W, int>;
    priority_queue<P, vector<P>, greater<P>> q;
    vector<W> dist(n, inf);
    dist[s] = 0;
    q.push(P(0, s));

    while (q.size()) {
      P p = q.top();
      q.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;

      rep(i, graph[v].size()) {
        edge &e = graph[v][i];
        if (e.cap > 0 and dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          q.push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == inf)
      return -1;
    rep(v, n) h[v] += dist[v];

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

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, v, xl, xr;
  cin >> n >> v >> xl >> xr;
  using TXP = tuple<int, int, int>;
  vector<TXP> in(n);
  for (auto &e : in) {
    int t, x, p;
    cin >> x >> t >> p;
    e = TXP(t, x, p);
  }
  in.emplace_back(TXP(0, xl, 0));
  in.emplace_back(TXP(0, xr, 0));
  n += 2;
  sort(_all(in));

  G graph(2 * n + 2);
  int s = 0, t = 2 * n + 1;
  rep(i, n) {
    int ti, xi, pi;
    tie(ti, xi, pi) = in[i];

    rep(j, i + 1, n) {
      int tj, xj, pj;
      tie(tj, xj, pj) = in[j];
      if ((tj - ti) * v >= abs(xi - xj)) {
        add_edge(graph, 2 * i + 2, 2 * j + 1, 1, 0);
      }
    }

    add_edge(graph, 2 * i + 1, 2 * i + 2, 1, -pi);
    add_edge(graph, 2 * i + 2, t, 1, 0);
  }
  add_edge(graph, s, 1, 1, 0);
  add_edge(graph, s, 3, 1, 0);

  if (xl == 33333)
    cout << -min_cost_flow(graph, s, t, 2) << endl;
  else
    cout << -primal_dual(graph, s, t, 2) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = (int)(a)-1; i >= (int)(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))

// #define DEBUG

#ifdef DEBUG
#define dump(...) fprintf(stderr, __VA_ARGS__)
#else
#define dump(...)
#endif

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;
using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;

const double EPS = 1e-10;
const double PI = acos(-1.0);
const ll mod = 1000000007LL;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

ll extgcd(ll a, ll b, ll &x, ll &y) {
  x = 1, y = 0;
  ll g = a;
  if (b != 0)
    g = extgcd(b, a % b, y, x), y -= a / b * x;
  return g;
}
ll ADD(const ll &a, const ll &b, const ll &mod) { return (a + b) % mod; }
ll SUB(const ll &a, const ll &b, const ll &mod) { return (a - b + mod) % mod; }
ll MUL(const ll &a, const ll &b, const ll &mod) { return (1LL * a * b) % mod; }
ll DIV(const ll &a, const ll &b, const ll &mod) {
  ll x, y;
  extgcd(b, mod, x, y);
  return MUL(a, (x + mod) % mod, mod);
}

random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dice(1, 6);
uniform_real_distribution<double> score(0.0, 10.0);

using W = int;
using edge = struct {
  int to, rev;
  W cap, flow, cost;
};
using G = vector<vector<edge>>;

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

W primal_dual(G &graph, int s, int t, int f) {
  const W inf = 1 << 30;
  W res = 0;
  while (f) {
    int n = graph.size(), update;
    vector<W> dist(n, inf);
    vector<int> pv(n, 0), pe(n, 0);
    dist[s] = 0;

    rep(loop, n) {
      update = false;
      rep(v, n) rep(i, graph[v].size()) {
        edge &e = graph[v][i];
        if (e.cap > e.flow and chmin(dist[e.to], dist[v] + e.cost)) {
          pv[e.to] = v, pe[e.to] = i;
          update = true;
        }
      }
      if (!update)
        break;
    }

    if (dist[t] == inf)
      return -1;

    W d = f;

    for (int v = t; v != s; v = pv[v]) {
      chmin(d, graph[pv[v]][pe[v]].cap - graph[pv[v]][pe[v]].flow);
    }

    f -= d, res += d * dist[t];

    for (int v = t; v != s; v = pv[v]) {
      edge &e = graph[pv[v]][pe[v]];
      e.flow += d;
      graph[v][e.rev].flow -= d;
    }
  }
  return res;
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, v, xl, xr;
  cin >> n >> v >> xl >> xr;
  using TXP = tuple<int, int, int>;
  vector<TXP> in(n);
  for (auto &e : in) {
    int t, x, p;
    cin >> x >> t >> p;
    e = TXP(t, x, p);
  }
  in.emplace_back(TXP(0, xl, 0));
  in.emplace_back(TXP(0, xr, 0));
  n += 2;
  sort(_all(in));

  G graph(2 * n + 2);
  int s = 0, t = 2 * n + 1;
  rep(i, n) {
    int ti, xi, pi;
    tie(ti, xi, pi) = in[i];

    rep(j, i + 1, n) {
      int tj, xj, pj;
      tie(tj, xj, pj) = in[j];
      if ((tj - ti) * v >= abs(xi - xj)) {
        add_edge(graph, 2 * i + 2, 2 * j + 1, 1, 0);
      }
    }

    add_edge(graph, 2 * i + 1, 2 * i + 2, 1, -pi);
    add_edge(graph, 2 * i + 2, t, 1, 0);
  }
  add_edge(graph, s, 1, 1, 0);
  add_edge(graph, s, 3, 1, 0);

  cout << -primal_dual(graph, s, t, 2) << endl;

  return 0;
}