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

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

// INSERT ABOVE HERE
template <typename T, typename U> void sort_pair(vector<T> &ts, vector<U> &us) {
  assert(ts.size() == us.size());
  using P = pair<T, U>;
  vector<P> vp;
  for (size_t i = 0; i < ts.size(); i++)
    vp.emplace_back(ts[i], us[i]);
  sort(vp.begin(), vp.end());
  for (size_t i = 0; i < ts.size(); i++)
    tie(ts[i], us[i]) = vp[i];
}

signed main() {
  Int n;
  while (cin >> n, n) {
    vector<Int> ps, ds, qs;
    for (Int i = 0; i < n; i++) {
      Int p, d;
      cin >> p >> d;
      if (d == 1) {
        qs.emplace_back(p);
        continue;
      }
      ps.emplace_back(p);
      ds.emplace_back(d);
    }
    sort(qs.begin(), qs.end());
    sort_pair(ps, ds);

    if (ps.empty() && n == 2) {
      cout << qs.back() - qs.front() << endl;
      continue;
    }

    Int ans = 0;
    for (Int i = 0; i + 1 < (Int)ps.size(); i++) {
      ans += ps[i + 1] - ps[i];
      ds[i]--;
      ds[i + 1]--;
    }

    vector<Int> as;
    for (Int i = 0; i < (Int)ps.size(); i++)
      for (Int j = 0; j < ds[i]; j++)
        as.emplace_back(ps[i]);

    assert(is_sorted(as.begin(), as.end()));
    if (as.size() < qs.size()) {
      cout << -1 << endl;
      continue;
    }

    const Int INF = 1e16;
    vector<Int> dp(as.size(), INF);
    vector<Int> nx(as.size(), INF);
    for (Int i = 0; i < (Int)qs.size(); i++) {
      Int idx = lower_bound(as.begin(), as.end(), qs[i]) - as.begin();
      Int res = INF * (i != 0);

      if (i != 0) {
        Int idy = lower_bound(as.begin(), as.end(), qs[i - 1]) - as.begin();
        for (Int j = idy - (n + 10); j <= idy + (n + 10); j++) {
          if (j < 0 || j >= (Int)as.size())
            continue;
          if (j < idx - (n + 10))
            chmin(res, dp[j]);
        }
      }
      {
        for (Int j = idx - (n + 10); j <= idx + (n + 10); j++) {
          if (j < 0 || j >= (Int)as.size())
            continue;
          chmin(nx[j], res + abs(as[j] - qs[i]));
          chmin(res, dp[j]);
        }
      }
      if (i != 0) {
        Int idy = lower_bound(as.begin(), as.end(), qs[i - 1]) - as.begin();
        for (Int j = idy - (n + 10); j <= idy + (n + 10); j++) {
          if (j < 0 || j >= (Int)as.size())
            continue;
          dp[j] = INF;
        }
      }
      {
        for (Int j = idx - (n + 10); j <= idx + (n + 10); j++) {
          if (j < 0 || j >= (Int)as.size())
            continue;
          dp[j] = nx[j];
          nx[j] = INF;
        }
      }
    }
    if (!qs.empty())
      ans += *min_element(dp.begin(), dp.end());
    cout << ans << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T> struct PrimalDual {
  struct edge {
    Int to;
    T cap, cost;
    Int rev;
    edge() {}
    edge(Int to, T cap, T cost, Int rev)
        : to(to), cap(cap), cost(cost), rev(rev) {}
  };

  T INF;
  vector<vector<edge>> G;
  vector<T> h, dist;
  vector<Int> prevv, preve;

  PrimalDual() {}
  PrimalDual(Int n, T INF)
      : INF(INF), G(n), h(n), dist(n), prevv(n), preve(n) {}

  void add_edge(Int from, Int to, T cap, T cost) {
    G[from].emplace_back(to, cap, cost, G[to].size());
    G[to].emplace_back(from, 0, -cost, G[from].size() - 1);
  }

  T flow(Int s, Int t, T f, Int &ok) {
    T res = 0;
    fill(h.begin(), h.end(), 0);
    while (f > 0) {
      using P = pair<T, Int>;
      priority_queue<P, vector<P>, greater<P>> que;
      fill(dist.begin(), dist.end(), INF);

      dist[s] = 0;
      que.emplace(dist[s], s);
      while (!que.empty()) {
        P p = que.top();
        que.pop();
        Int v = p.second;
        if (dist[v] < p.first)
          continue;
        for (Int i = 0; i < (Int)G[v].size(); i++) {
          edge &e = G[v][i];
          if (e.cap == 0)
            continue;
          if (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;
            que.emplace(dist[e.to], e.to);
          }
        }
      }
      if (dist[t] == INF)
        return ok = 0;

      for (Int v = 0; v < (Int)h.size(); v++)
        h[v] += dist[v];

      T d = f;
      for (Int v = t; v != s; v = prevv[v])
        d = min(d, G[prevv[v]][preve[v]].cap);

      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;
      }
    }
    ok = 1;
    return res;
  }
};

template <typename T> vector<T> compress(vector<T> v) {
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  return v;
}

template <typename T> map<T, Int> dict(const vector<T> &v) {
  map<T, Int> res;
  for (Int i = 0; i < (Int)v.size(); i++)
    res[v[i]] = i;
  return res;
}

struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;

// INSERT ABOVE HERE
signed main() {
  Int n;
  while (cin >> n, n) {
    vector<Int> p(n), d(n);
    for (Int i = 0; i < n; i++)
      cin >> p[i] >> d[i];
    {
      Int s = 0;
      for (Int i = 0; i < n; i++)
        s += d[i];
      if (s < 2 * (n - 1)) {
        cout << -1 << endl;
        continue;
      }
    }
    {
      using P = pair<Int, Int>;
      vector<P> vp;
      for (Int i = 0; i < n; i++)
        vp.emplace_back(p[i], d[i]);
      sort(vp.begin(), vp.end());
      for (Int i = 0; i < n; i++)
        tie(p[i], d[i]) = vp[i];
    }
    if (n == 2) {
      cout << p.back() - p.front() << endl;
      continue;
    }

    const Int INF = 1e12;
    PrimalDual<Int> G(n + 2, INF);
    Int S = n, T = n + 1;

    vector<Int> vs, used(n, 0);
    for (Int i = 0; i < n; i++) {
      if (d[i] == 1)
        continue;
      used[i] = 1;
      vs.emplace_back(i);
    }

    for (Int i = 0; i + 1 < (Int)vs.size(); i++) {
      d[vs[i]]--;
      d[vs[i + 1]]--;
    }

    vector<Int> us;
    for (Int i = 0; i < n; i++) {
      if (!used[i])
        continue;
      if (d[i]) {
        G.add_edge(i, T, d[i], 0);
        us.emplace_back(i);
      }
    }
    for (Int i = 0; i + 1 < (Int)us.size(); i++) {
      G.add_edge(us[i], us[i + 1], n + 1, p[us[i + 1]] - p[us[i]]);
      G.add_edge(us[i + 1], us[i], n + 1, p[us[i + 1]] - p[us[i]]);
    }

    vector<Int> prv(n, -1), nxt(n, -1);
    for (Int i = 0, lst = -1; i < n; i++) {
      if (used[i] && d[i])
        lst = i;
      else
        prv[i] = lst;
    }
    for (Int i = n - 1, lst = -1; i >= 0; i--) {
      if (used[i] && d[i])
        lst = i;
      else
        nxt[i] = lst;
    }

    Int cnt = 0;
    for (Int i = 0; i < n; i++) {
      if (used[i])
        continue;
      cnt++;
      G.add_edge(S, i, 1, 0);
      if (~prv[i])
        G.add_edge(i, prv[i], 1, abs(p[i] - p[prv[i]]));
      if (~nxt[i])
        G.add_edge(i, nxt[i], 1, abs(p[i] - p[nxt[i]]));
    }

    Int ok = 0;
    Int ans = G.flow(S, T, cnt, ok);
    assert(ok);
    ans += p[vs.back()] - p[vs.front()];
    cout << ans << endl;
  }
  return 0;
}