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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
#define MOD 1000000007ll
// #define INF 1000000000ll
#define EPS 1e-10
#define FOR(i, n, m) for (ll i = n; i < (ll)m; i++)
#define REP(i, n) FOR(i, 0, n)
#define DUMP(a)                                                                \\
  REP(d, a.size()) {                                                           \\
    cout << a[d];                                                              \\
    if (d != a.size() - 1)                                                     \\
      cout << " ";                                                             \\
    else                                                                       \\
      cout << endl;                                                            \\
  }
#define ALL(v) v.begin(), v.end()
#define UNIQUE(v)                                                              \\
  sort(ALL(v));                                                                \\
  v.erase(unique(ALL(v)), v.end());
#define pb push_back

using Flow = ll;
using Cost = ll;
const ll MAX_V = 5000;
const Cost INF = std::numeric_limits<Cost>::max() / 8;

struct PrimalDual {
  struct Edge {
    ll d;
    Flow c, f;
    Cost w;
    ll r, is_r;
    Edge(ll d_, Flow c_, Flow f_, Cost w_, ll r_, bool is_r_)
        : d(d_), c(c_), f(f_), w(w_), r(r_), is_r(is_r_) {}
  };

  ll n;
  std::vector<std::vector<Edge>> g;
  PrimalDual(ll n_) : n(n_), g(std::vector<std::vector<Edge>>(n_)) {}

  void add_edge(ll src, ll dst, Flow cap, Cost cost) { // 有向辺
    ll rsrc = g[dst].size();
    ll rdst = g[src].size();
    g[src].emplace_back(dst, cap, 0, cost, rsrc, false);
    g[dst].emplace_back(src, cap, cap, -cost, rdst, true);
  }

  Cost solve(ll s, ll t, Flow f) {
    vector<vector<Edge>> ng = g;
    Cost res = 0;
    static Cost h[MAX_V + 10], dist[MAX_V];
    static int prevv[MAX_V + 10], preve[MAX_V + 10];
    // std::vector<Cost> h(g.size()), dist(g.size());
    // std::vector<int> prevv(g.size()), preve(g.size());

    using pcv = std::pair<Cost, ll>;
    std::priority_queue<pcv, std::vector<pcv>, std::greater<pcv>> q;
    std::fill(h, h + n, 0);
    while (f > 0) {
      std::fill(dist, dist + n, INF);
      dist[s] = 0;
      q.emplace(0, s);
      while (q.size()) {
        Cost cd;
        ll v;
        std::tie(cd, v) = q.top();
        q.pop();
        if (dist[v] < cd)
          continue;
        for (ll i = 0; i < (ll)(ng[v].size()); ++i) {
          Edge &e = ng[v][i];
          if (residue(e) == 0)
            continue;
          if (dist[e.d] + h[e.d] > cd + h[v] + e.w) {
            dist[e.d] = dist[v] + e.w + h[v] - h[e.d];
            prevv[e.d] = v;
            preve[e.d] = i;
            q.emplace(dist[e.d], e.d);
          }
        }
      }

      if (dist[t] == INF)
        return INF; // 経路が見つからなかった

      // s-t 間最短路に沿って目一杯流す
      for (ll i = 0; i < n; ++i)
        h[i] += dist[i];
      Flow d = f;
      for (ll v = t; v != s; v = prevv[v]) {
        d = std::min(d, residue(ng[prevv[v]][preve[v]]));
      }
      f -= d;
      res += d * h[t];
      for (ll v = t; v != s; v = prevv[v]) {
        Edge &e = ng[prevv[v]][preve[v]];
        e.f += d;
        ng[v][e.r].f -= d;
      }
    }
    return res;
  }

  Flow residue(const Edge &e) { return e.c - e.f; }

  void show() {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < (int)(g[i].size()); ++j) {
        Edge &e = g[i][j];
        if (e.is_r)
          continue;
        printf("%3d->%3d (flow:%d)\\n", i, (int)e.d, (int)e.f);
      }
    }
  }
};

ll n;

ll solve() {
  vector<ll> a(n);
  vector<ll> b(n);
  REP(i, n) cin >> a[i] >> b[i];
  vector<ll> num;
  REP(i, n) num.pb(a[i]);
  REP(i, n) num.pb(b[i]);
  UNIQUE(num);
  PrimalDual pd(n + (ll)num.size() + 3);
  REP(i, n) pd.add_edge(0, 1 + i, 1, 0);
  REP(i, (ll)num.size()) pd.add_edge(1 + n + i, n + (ll)num.size() + 1, 1, 0);
  pd.add_edge(n + (ll)num.size() + 2, n + (ll)num.size() + 1, INF, 0);
  REP(i, n) {
    ll idxa = (lower_bound(ALL(num), a[i]) - num.begin());
    ll idxb = (lower_bound(ALL(num), b[i]) - num.begin());
    pd.add_edge(1 + i, 1 + n + idxa, 1, -b[i]);
    pd.add_edge(1 + i, 1 + n + idxb, 1, -a[i]);
    pd.add_edge(1 + i, n + (ll)num.size() + 2, 1, 0);
  }
  return -pd.solve(0, n + (ll)num.size() + 1, n);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  cout << solve() << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
#define MOD 1000000007ll
// #define INF 1000000000ll
#define EPS 1e-10
#define FOR(i, n, m) for (ll i = n; i < (ll)m; i++)
#define REP(i, n) FOR(i, 0, n)
#define DUMP(a)                                                                \\
  REP(d, a.size()) {                                                           \\
    cout << a[d];                                                              \\
    if (d != a.size() - 1)                                                     \\
      cout << " ";                                                             \\
    else                                                                       \\
      cout << endl;                                                            \\
  }
#define ALL(v) v.begin(), v.end()
#define UNIQUE(v)                                                              \\
  sort(ALL(v));                                                                \\
  v.erase(unique(ALL(v)), v.end());
#define pb push_back

using Flow = ll;
using Cost = ll;
const ll MAX_V = 5000;
const Cost INF = std::numeric_limits<Cost>::max() / 8;

struct PrimalDual {
  struct Edge {
    ll d;
    Flow c, f;
    Cost w;
    ll r, is_r;
    Edge(ll d_, Flow c_, Flow f_, Cost w_, ll r_, bool is_r_)
        : d(d_), c(c_), f(f_), w(w_), r(r_), is_r(is_r_) {}
  };

  ll n;
  std::vector<std::vector<Edge>> g;
  PrimalDual(ll n_) : n(n_), g(std::vector<std::vector<Edge>>(n_)) {}

  void add_edge(ll src, ll dst, Flow cap, Cost cost) { // 有向辺
    ll rsrc = g[dst].size();
    ll rdst = g[src].size();
    g[src].emplace_back(dst, cap, 0, cost, rsrc, false);
    g[dst].emplace_back(src, cap, cap, -cost, rdst, true);
  }

  Cost solve(ll s, ll t, Flow f) {
    vector<vector<Edge>> ng = g;
    Cost res = 0;
    static Cost h[MAX_V + 10], dist[MAX_V];
    static int prevv[MAX_V + 10], preve[MAX_V + 10];
    // std::vector<Cost> h(g.size()), dist(g.size());
    // std::vector<int> prevv(g.size()), preve(g.size());

    using pcv = std::pair<Cost, ll>;
    std::priority_queue<pcv, std::vector<pcv>, std::greater<pcv>> q;
    std::fill(h, h + n, 0);
    while (f > 0) {
      std::fill(dist, dist + n, INF);
      dist[s] = 0;
      q.emplace(0, s);
      while (q.size()) {
        Cost cd;
        ll v;
        std::tie(cd, v) = q.top();
        q.pop();
        if (dist[v] < cd)
          continue;
        for (ll i = 0; i < (ll)(ng[v].size()); ++i) {
          Edge &e = ng[v][i];
          if (residue(e) == 0)
            continue;
          if (dist[e.d] + h[e.d] > cd + h[v] + e.w) {
            dist[e.d] = dist[v] + e.w + h[v] - h[e.d];
            prevv[e.d] = v;
            preve[e.d] = i;
            q.emplace(dist[e.d], e.d);
          }
        }
      }

      if (dist[t] == INF)
        return INF; // 経路が見つからなかった

      // s-t 間最短路に沿って目一杯流す
      for (ll i = 0; i < n; ++i)
        h[i] += dist[i];
      Flow d = f;
      for (ll v = t; v != s; v = prevv[v]) {
        d = std::min(d, residue(ng[prevv[v]][preve[v]]));
      }
      f -= d;
      res += d * h[t];
      for (ll v = t; v != s; v = prevv[v]) {
        Edge &e = ng[prevv[v]][preve[v]];
        e.f += d;
        ng[v][e.r].f -= d;
      }
    }
    return res;
  }

  Flow residue(const Edge &e) { return e.c - e.f; }

  void show() {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < (int)(g[i].size()); ++j) {
        Edge &e = g[i][j];
        if (e.is_r)
          continue;
        printf("%3d->%3d (flow:%d)\\n", i, (int)e.d, (int)e.f);
      }
    }
  }
};

ll n;

ll solve() {
  vector<ll> a(n);
  vector<ll> b(n);
  REP(i, n) cin >> a[i] >> b[i];
  vector<ll> num;
  REP(i, n) num.pb(a[i]);
  REP(i, n) num.pb(b[i]);
  UNIQUE(num);
  PrimalDual pd(n + (ll)num.size() + 2);
  REP(i, n) pd.add_edge(0, 1 + i, 1, 0);
  REP(i, (ll)num.size()) pd.add_edge(1 + n + i, n + (ll)num.size() + 1, 1, 0);
  REP(i, n) {
    ll idxa = (lower_bound(ALL(num), a[i]) - num.begin());
    ll idxb = (lower_bound(ALL(num), b[i]) - num.begin());
    pd.add_edge(1 + i, 1 + n + idxa, 1, -b[i]);
    pd.add_edge(1 + i, 1 + n + idxb, 1, -a[i]);
  }
  ll ans = 0;
  for (ll f = 1; f <= n; f++) {
    ll tmp = pd.solve(0, n + (ll)num.size() + 1, f);
    if (tmp != INF)
      ans = max(ans, -tmp);
  }
  return ans;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  cout << solve() << endl;
  return 0;
}