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

#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) { return (abs(a) <= EPS) ? 0 : (a < 0 ? -1 : 1); }
int sgn(D a, D b) { return sgn(a - b); }

struct Pt2 {
  D x, y;
  Pt2() {}
  Pt2(D _x, D _y) : x(_x), y(_y) {}
  Pt2 operator-(const Pt2 &r) const { return Pt2(x - r.x, y - r.y); }
  bool operator<(const Pt2 &r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(const Pt2 &r) const { return sgn((*this - r).rabs()) == 0; }
  D abs() const { return sqrt(x * x + y * y); }
  D rabs() const { return max(std::abs(x), std::abs(y)); }
};
ostream &operator<<(ostream &os, const Pt2 &p) {
  return os << "(" << p.x << ", " << p.y << ")";
}
using P = Pt2;

template <class C, class D, class E> struct MinCostFlow {
  static constexpr D INF = numeric_limits<D>::max();
  D eps;
  VV<E> g;
  int s, t;
  C nc, cap_flow;
  D nd, flow;

  V<D> dual;
  V<int> pv, pe;

  V<int> visited;
  int vid = 114514;
  MinCostFlow(VV<E> _g, int s, int t, D _eps, bool neg)
      : g(_g), s(s), t(t), eps(_eps), cap_flow(0), flow(0) {
    assert(s != t);
    dual = V<D>(g.size());
    pv = V<int>(g.size());
    pe = V<int>(g.size());
    visited = V<int>(g.size());
    dual_ref(neg);
  }

  C single_flow(C c) {
    if (nd == INF)
      return nc;
    c = min(c, nc);
    for (int v = t; v != s; v = pv[v]) {
      E &e = g[pv[v]][pe[v]];
      e.cap -= c;
      g[v][e.rev].cap += c;
    }
    cap_flow += c;
    flow += nd * c;
    nc -= c;
    if (!nc)
      dual_ref(false);
    return c;
  }
  C dfs(int v, C f) {
    if (v == t)
      return f;
    visited[v] = vid;
    for (E &e : g[v]) {
      D ed = e.dist + dual[v] - dual[e.to];
      if (!e.cap || visited[e.to] == vid)
        continue;
      if (ed != D(0))
        continue;
      C u = dfs(e.to, min(f, e.cap));
      if (u > 0) {
        e.cap -= u;
        g[e.to][e.rev].cap += u;
        return u;
      }
    }
    return 0;
  }

  C multi_flow(C c) {
    C sm = 0;
    while (true) {
      vid++;
      C res = dfs(s, c);
      sm += res;
      flow += nd * res;
      if (!c || !res)
        break;
      c -= res;
    }
    cap_flow += sm;
    dual_ref(false);
    return sm;
  }
  void max_flow(C c) {
    while (c) {
      C f = single_flow(c);
      if (!f)
        break;
      c -= f;
    }
  }

  void dual_ref(bool neg) {
    V<D> dist(g.size(), INF);
    fill(begin(pv), end(pv), -1);
    fill(begin(pe), end(pe), -1);

    using P = pair<D, int>;
    queue<int> ref_v;
    priority_queue<P, vector<P>, greater<P>> que1;
    queue<P> que2;
    auto empty = [&] { return (!neg) ? que1.empty() : que2.empty(); };
    auto push = [&](P p) { (!neg) ? que1.push(p) : que2.push(p); };
    auto pop = [&]() {
      P p = (!neg) ? que1.top() : que2.front();
      (!neg) ? que1.pop() : que2.pop();
      return p;
    };
    push(P(D(0), s));
    dist[s] = D(0);
    while (!empty()) {
      P p = pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      if (!neg) {
        if (v == t)
          break;
        ref_v.push(v);
      }
      for (int i = 0; i < int(g[v].size()); i++) {
        E e = g[v][i];
        D ed = e.dist + dual[v] - dual[e.to];
        if (e.cap && dist[e.to] > dist[v] + ed + eps) {
          dist[e.to] = dist[v] + ed;
          pv[e.to] = v;
          pe[e.to] = i;
          push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == INF) {
      nd = INF;
      nc = 0;
      return;
    }
    if (!neg) {
      while (ref_v.size()) {
        int v = ref_v.front();
        ref_v.pop();
        if (dist[v] >= dist[t])
          continue;
        dual[v] += dist[v] - dist[t];
      }
    } else {
      for (int v = 0; v < int(g.size()); v++) {
        dual[v] += dist[v];
      }
    }
    nd = dual[t] - dual[s];
    if (!neg)
      assert(0 <= nd);
    nc = numeric_limits<C>::max();
    for (int v = t; v != s; v = pv[v]) {
      nc = min(nc, g[pv[v]][pe[v]].cap);
    }
  }
};

template <class C, class D, class E>
auto min_cost_flow(const VV<E> &g, int s, int t, D eps, bool neg = false) {
  return MinCostFlow<C, D, E>(g, s, t, eps, neg);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(20) << fixed;

  D ans = 0;

  int n;
  cin >> n;
  D x, y;
  P p;
  cin >> x >> y;
  p = P(x, y);
  map<P, int> mp;
  for (int i = 0; i < n; i++) {
    P p, q;
    cin >> x >> y;
    p = P(x, y);
    mp[p]++;
    cin >> x >> y;
    q = P(x, y);
    mp[q]--;
    ans += (p - q).abs();
  }

  using Pi = pair<P, int>;
  V<Pi> up, dw;
  for (auto p : mp) {
    if (p.second == 0)
      continue;
    if (p.second > 0) {
      up.push_back(p);
    } else {
      dw.push_back(Pi(p.first, -p.second));
    }
  }

  int l = int(up.size()), r = int(dw.size());

  struct E {
    int to, cap;
    D dist;
    int rev;
  };
  int sv = l + r, tv = sv + 1;
  VV<E> g(l + r + 2);
  auto add_edge = [&](int from, int to, int cap, D dist) {
    g[from].push_back(E{to, cap, dist, int(g[to].size())});
    g[to].push_back(E{from, 0, -dist, int(g[from].size()) - 1});
  };

  for (int i = 0; i < l; i++) {
    add_edge(sv, i, up[i].second, 0);
  }
  for (int j = 0; j < r; j++) {
    add_edge(l + j, tv, dw[j].second, 0);
  }
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      add_edge(i, l + j, TEN(9), (up[i].first - dw[j].first).abs());
    }
  }

  auto res = min_cost_flow<int, D>(g, sv, tv, EPS, false);
  res.max_flow(TEN(9));

  cout << ans + res.flow << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) { return (abs(a) <= EPS) ? 0 : (a < 0 ? -1 : 1); }
int sgn(D a, D b) { return sgn(a - b); }

struct Pt2 {
  D x, y;
  Pt2() {}
  Pt2(D _x, D _y) : x(_x), y(_y) {}
  Pt2 operator-(const Pt2 &r) const { return Pt2(x - r.x, y - r.y); }
  bool operator<(const Pt2 &r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(const Pt2 &r) const { return sgn((*this - r).rabs()) == 0; }
  D abs() const { return sqrt(x * x + y * y); }
  D rabs() const { return max(std::abs(x), std::abs(y)); }
};
ostream &operator<<(ostream &os, const Pt2 &p) {
  return os << "(" << p.x << ", " << p.y << ")";
}
using P = Pt2;

template <class C, class D, class E> struct MinCostFlow {
  static constexpr D INF = numeric_limits<D>::max();
  VV<E> g;
  int s, t;
  C nc, cap_flow;
  D nd, flow;

  V<D> dual;
  V<int> pv, pe;

  V<int> visited;
  int vid = 114514;
  MinCostFlow(VV<E> g, int s, int t, bool neg)
      : g(g), s(s), t(t), cap_flow(0), flow(0) {
    assert(s != t);
    dual = V<D>(g.size());
    pv = V<int>(g.size());
    pe = V<int>(g.size());
    visited = V<int>(g.size());
    dual_ref(neg);
  }

  C single_flow(C c) {
    if (nd == INF)
      return nc;
    c = min(c, nc);
    for (int v = t; v != s; v = pv[v]) {
      E &e = g[pv[v]][pe[v]];
      e.cap -= c;
      g[v][e.rev].cap += c;
    }
    cap_flow += c;
    flow += nd * c;
    nc -= c;
    if (!nc)
      dual_ref(false);
    return c;
  }
  C dfs(int v, C f) {
    if (v == t)
      return f;
    visited[v] = vid;
    for (E &e : g[v]) {
      D ed = e.dist + dual[v] - dual[e.to];
      if (!e.cap || visited[e.to] == vid)
        continue;
      if (ed != D(0))
        continue;
      C u = dfs(e.to, min(f, e.cap));
      if (u > 0) {
        e.cap -= u;
        g[e.to][e.rev].cap += u;
        return u;
      }
    }
    return 0;
  }

  C multi_flow(C c) {
    C sm = 0;
    while (true) {
      vid++;
      C res = dfs(s, c);
      sm += res;
      flow += nd * res;
      if (!c || !res)
        break;
      c -= res;
    }
    cap_flow += sm;
    dual_ref(false);
    return sm;
  }
  void max_flow(C c) {
    while (c) {
      C f = single_flow(c);
      if (!f)
        break;
      c -= f;
    }
  }

  void dual_ref(bool neg) {
    V<D> dist(g.size(), INF);
    fill(begin(pv), end(pv), -1);
    fill(begin(pe), end(pe), -1);

    using P = pair<D, int>;
    queue<int> ref_v;
    priority_queue<P, vector<P>, greater<P>> que1;
    queue<P> que2;
    auto empty = [&] { return (!neg) ? que1.empty() : que2.empty(); };
    auto push = [&](P p) { (!neg) ? que1.push(p) : que2.push(p); };
    auto pop = [&]() {
      P p = (!neg) ? que1.top() : que2.front();
      (!neg) ? que1.pop() : que2.pop();
      return p;
    };
    push(P(D(0), s));
    dist[s] = D(0);
    while (!empty()) {
      P p = pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      if (!neg) {
        if (v == t)
          break;
        ref_v.push(v);
      }
      for (int i = 0; i < int(g[v].size()); i++) {
        E e = g[v][i];
        D ed = e.dist + dual[v] - dual[e.to];
        if (e.cap && dist[e.to] > dist[v] + ed) {
          dist[e.to] = dist[v] + ed;
          pv[e.to] = v;
          pe[e.to] = i;
          push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == INF) {
      nd = INF;
      nc = 0;
      return;
    }
    if (!neg) {
      while (ref_v.size()) {
        int v = ref_v.front();
        ref_v.pop();
        if (dist[v] >= dist[t])
          continue;
        dual[v] += dist[v] - dist[t];
      }
    } else {
      for (int v = 0; v < int(g.size()); v++) {
        dual[v] += dist[v];
      }
    }
    nd = dual[t] - dual[s];
    if (!neg)
      assert(0 <= nd);
    nc = numeric_limits<C>::max();
    for (int v = t; v != s; v = pv[v]) {
      nc = min(nc, g[pv[v]][pe[v]].cap);
    }
  }
};

template <class C, class D, class E>
auto min_cost_flow(const VV<E> &g, int s, int t, bool neg = false) {
  return MinCostFlow<C, D, E>(g, s, t, neg);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(20) << fixed;

  D ans = 0;

  int n;
  cin >> n;
  D x, y;
  P p;
  cin >> x >> y;
  p = P(x, y);
  map<P, int> mp;
  for (int i = 0; i < n; i++) {
    P p, q;
    cin >> x >> y;
    p = P(x, y);
    mp[p]++;
    cin >> x >> y;
    q = P(x, y);
    mp[q]--;
    ans += (p - q).abs();
  }

  using Pi = pair<P, int>;
  V<Pi> up, dw;
  for (auto p : mp) {
    if (p.second == 0)
      continue;
    if (p.second > 0) {
      up.push_back(p);
    } else {
      dw.push_back(Pi(p.first, -p.second));
    }
  }

  int l = int(up.size()), r = int(dw.size());

  struct E {
    int to, cap;
    D dist;
    int rev;
  };
  int sv = l + r, tv = sv + 1;
  VV<E> g(l + r + 2);
  auto add_edge = [&](int from, int to, int cap, D dist) {
    g[from].push_back(E{to, cap, dist, int(g[to].size())});
    g[to].push_back(E{from, 0, -dist, int(g[from].size()) - 1});
  };

  for (int i = 0; i < l; i++) {
    add_edge(sv, i, up[i].second, 0);
  }
  for (int j = 0; j < r; j++) {
    add_edge(l + j, tv, dw[j].second, 0);
  }
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      add_edge(i, l + j, TEN(9), (up[i].first - dw[j].first).abs());
    }
  }

  auto res = min_cost_flow<int, D>(g, sv, tv, false);
  res.max_flow(TEN(9));

  cout << ans + res.flow << endl;
  return 0;
}