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

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int inf = (int)1.05e9;

struct Edge {
  int to, cap, cost, rev;
  Edge(int to, int cap, int cost, int rev)
      : to(to), cap(cap), cost(cost), rev(rev) {}
};

struct Graph {
  vector<vector<Edge>> g;

  void init(int n) { g.resize(n); }

  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 push_mincost_flow(int s, int t, int f) {
    int ans = 0;
    vector<int> h(g.size(), 0);

    while (f > 0) {

      vector<int> dist(g.size(), inf);
      vector<pair<int, int>> his(g.size());
      priority_queue<pair<int, int>> q;

      q.push(make_pair(0, s));
      dist[s] = 0;

      while (!q.empty()) {
        int d = -q.top().first;
        int v = q.top().second;
        q.pop();
        if (dist[v] < d)
          continue;
        for (int i = 0; i < g[v].size(); ++i) {
          Edge &e = g[v][i];
          if (e.cap <= 0)
            continue;
          int p = d + e.cost + h[v] - h[e.to];
          if (dist[e.to] <= p)
            continue;
          dist[e.to] = p;
          his[e.to] = make_pair(v, i);
          q.push(make_pair(-p, e.to));
        }
      }

      for (int i = 0; i < g.size(); ++i)
        h[i] += dist[i];

      if (h[t] >= inf)
        return inf;

      int cap = f;

      for (int v = t; v != s; v = his[v].first)
        cap = min(cap, g[his[v].first][his[v].second].cap);
      for (int v = t; v != s; v = his[v].first) {
        Edge &e = g[his[v].first][his[v].second];
        e.cap -= cap;
        g[e.to][e.rev].cap += cap;
      }

      f -= cap;
      ans += cap * h[t];
    }

    return ans;
  }
};

int main() {
  int n;
  vector<int> a, b;
  vector<int> hs;

  scanf("%d", &n);
  a.resize(n);
  b.resize(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &a[i], &b[i]);
    if (a[i] < b[i])
      swap(a[i], b[i]);
    hs.push_back(a[i]);
    hs.push_back(b[i]);
  }
  sort(hs.begin(), hs.end());
  hs.erase(unique(hs.begin(), hs.end()), hs.end());

  Graph g;

  g.init(2 + n + hs.size() + 1);

  for (int i = 0; i < n; ++i) {

    int v = 2 + i;
    int av = lower_bound(hs.begin(), hs.end(), a[i]) - hs.begin() + (2 + n);
    int bv = lower_bound(hs.begin(), hs.end(), b[i]) - hs.begin() + (2 + n);
    int cv = 2 + n + hs.size();

    g.add_edge(0, v, 1, 0);
    g.add_edge(v, av, 1, a[i] - b[i]);
    g.add_edge(v, bv, 1, 0);
    g.add_edge(v, cv, 1, a[i]);
  }

  for (int i = 0; i < hs.size(); ++i)
    g.add_edge(2 + n + i, 1, 1, 0);
  g.add_edge(2 + n + hs.size(), 1, n, 0);

  int c = g.push_mincost_flow(0, 1, n);
  int total = 0;
  for (int i = 0; i < n; ++i)
    total += a[i];

  int ans = total - c;
  printf("%d\\n", ans);

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int inf = (int)1e9;

struct Edge {
  int to, cap, cost, rev;
  Edge(int to, int cap, int cost, int rev)
      : to(to), cap(cap), cost(cost), rev(rev) {}
};

struct Graph {
  vector<vector<Edge>> g;

  void init(int n) { g.resize(n); }

  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[to].size() - 1));
  }

  int push_mincost_flow(int s, int t, int f) {
    int ans = 0;
    vector<int> h(g.size(), 0);

    while (f > 0) {

      vector<int> dist(g.size(), inf);
      vector<pair<int, int>> his(g.size());
      priority_queue<pair<int, int>> q;

      q.push(make_pair(0, s));
      while (!q.empty()) {
        int d = -q.top().first;
        int v = q.top().second;
        q.pop();
        if (dist[v] < d)
          continue;
        dist[v] = d;
        for (int i = 0; i < g[v].size(); ++i) {
          Edge &e = g[v][i];
          if (e.cap <= 0)
            continue;
          int p = d + e.cost + h[e.to] - h[v];
          if (dist[e.to] <= p)
            continue;
          dist[e.to] = p;
          his[e.to] = make_pair(v, i);
          q.push(make_pair(-p, e.to));
        }
      }

      for (int i = 0; i < g.size(); ++i)
        h[i] += dist[i];

      if (h[t] >= inf)
        return inf;

      int cap = f;

      for (int v = t; v != s; v = his[v].first)
        cap = min(cap, g[his[v].first][his[v].second].cap);
      for (int v = t; v != s; v = his[v].first) {
        Edge &e = g[his[v].first][his[v].second];
        e.cap -= cap;
        g[e.to][e.rev].cap += cap;
      }

      f -= cap;
      ans += cap * h[t];
    }

    return ans;
  }
};

int main() {
  int n;
  vector<int> a, b;
  vector<int> hs;

  scanf("%d", &n);
  a.resize(n);
  b.resize(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &a[i], &b[i]);
    if (a[i] < b[i])
      swap(a[i], b[i]);
    hs.push_back(a[i]);
    hs.push_back(b[i]);
  }
  sort(hs.begin(), hs.end());
  hs.erase(unique(hs.begin(), hs.end()), hs.end());

  Graph g;

  g.init(2 + n + hs.size() + 1);

  for (int i = 0; i < n; ++i) {

    int v = 2 + i;
    int av = lower_bound(hs.begin(), hs.end(), a[i]) - hs.begin() + (2 + n);
    int bv = lower_bound(hs.begin(), hs.end(), b[i]) - hs.begin() + (2 + n);
    int cv = 2 + n + hs.size();

    g.add_edge(0, v, 1, 0);
    g.add_edge(v, av, 1, a[i] - b[i]);
    g.add_edge(v, bv, 1, 0);
    g.add_edge(v, cv, 1, a[i]);
  }

  for (int i = 0; i < hs.size(); ++i)
    g.add_edge(2 + n + i, 1, 1, 0);
  g.add_edge(2 + n + hs.size(), 1, n, 0);

  int c = g.push_mincost_flow(0, 1, n);
  int total = 0;
  for (int i = 0; i < n; ++i)
    total += a[i];

  int ans = total - c;
  printf("%d\\n", ans);

  return 0;
}