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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

// < "D:\\D_Download\\Visual Studio
// 2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

struct Compress {
  map<int, int> mp;
  map<int, int> revmp;

  Compress(vector<int> vs) {
    sort(vs.begin(), vs.end());
    vs.erase(unique(vs.begin(), vs.end()), vs.end());
    for (int i = 0; i < vs.size(); ++i) {
      mp[vs[i]] = i;
      revmp[i] = vs[i];
    }
  }
};
typedef long long Weight;
struct Edge {
  int src, dest;
  int cap, rev;
  Weight weight;
  bool operator<(const Edge &rhs) const { return weight > rhs.weight; }
};

const int V = 4000;
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
Weight h[V];            //??????????????£???
Weight dist[V];         //???????????¢
int prevv[V], preve[V]; //??´???????????¨??????

void add_edge(Graph &g, int src, int dest, int cap, int weight) {
  g[src].push_back(Edge{src, dest, cap, (int)g[dest].size(), weight});
  g[dest].push_back(Edge{dest, src, 0, (int)g[src].size() - 1, -weight});
}
#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 2147483647;
const long long int L_INF = 9223372036854775807;
Weight min_cost_flow(Graph &g, int s, int t, int f) {
  Weight res = 0;
  memset(h, 0, sizeof(h));
  typedef pair<Weight, int> P;
  while (f > 0) {
    priority_queue<P, vector<P>, greater<P>> que;
    fill(dist, dist + V, INF);
    dist[s] = 0;
    que.push(P(0, s));
    while (!que.empty()) {
      P p = que.top();
      que.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      REP(i, g[v].size()) {
        Edge &e = g[v][i];
        if (e.cap > 0 && dist[e.dest] > dist[v] + e.weight + h[v] - h[e.dest]) {
          dist[e.dest] = dist[v] + e.weight + h[v] - h[e.dest];
          prevv[e.dest] = v;
          preve[e.dest] = i;
          que.push(P(dist[e.dest], e.dest));
        }
      }
    }
    if (dist[t] == INF)
      return -1;
    REP(v, V) h[v] += dist[v];

    int 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;
    }
  }
  return res;
}
int main() {
  int N;
  cin >> N;
  vector<int> vs;
  vector<pair<long long int, long long int>> ps;
  for (int i = 0; i < N; ++i) {
    long long int a, b;
    cin >> a >> b;
    ps.emplace_back(a, b);
    vs.push_back(a);
    vs.push_back(b);
  }
  Compress cp(vs);

  const int start = 0;
  const int snode = start + 1;
  const int he = snode + N;
  const int goal = he + 2 * N;
  Graph g(goal + 1);
  for (int i = 0; i < N; ++i) {
    add_edge(g, start, snode + i, 1, 0);
  }
  for (int i = 0; i < N; ++i) {
    add_edge(g, snode + i, he + cp.mp[ps[i].second], 1, 1000000 - ps[i].first);
    add_edge(g, snode + i, he + cp.mp[ps[i].first], 1, 1000000 - ps[i].second);
    add_edge(g, snode + i, goal, 1, 1000000);
  }
  for (int i = 0; i < 2 * N; ++i) {
    add_edge(g, he + i, goal, 1, 0);
  }
  auto p = min_cost_flow(g, start, goal, N);
  long long int ans = 1000000 * N - p;
  cout << ans << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

// < "D:\\D_Download\\Visual Studio
// 2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

struct Compress {
  map<int, int> mp;
  map<int, int> revmp;

  Compress(vector<int> vs) {
    sort(vs.begin(), vs.end());
    vs.erase(unique(vs.begin(), vs.end()), vs.end());
    for (int i = 0; i < vs.size(); ++i) {
      mp[vs[i]] = i;
      revmp[i] = vs[i];
    }
  }
};

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()

const int INF = 2147483647;
const long long int L_INF = 9223372036854775807;

typedef long long int Weight;
struct Edge {
  int src, dst;
  Weight capacity;
  Weight cost;
  Edge(int src, int dst, Weight acap, Weight acost)
      : src(src), dst(dst), capacity(acap), cost(acost) {}
};
bool operator<(const Edge &e, const Edge &f) { return e.cost > f.cost; }
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;
#define RESIDUE(s, t) (capacity[s][t] - flow[s][t])

#define RCOST(u, v) (cost[u][v] + h[u] - h[v])

//??°?????????????????§???????????????????????¨?????????

// Graph &ag
//????????§???????????????(u, v, capacity, cost) ??????????????????(u, v, 0,
//-cost)
//???????????°????????????????????¶?????????????????§????´???°????????§???????????°???????????????
// int s, int t
//?????????????§??????¨?????????
//?????????
//?????¨??¨????????????????????????
pair<Weight, Weight> minimumCostFlow(const Graph &ag, int s, int t) {
  // check???????´???°??????????????£???????????????
  Graph g(ag);
  for (int i = 0; i < ag.size(); ++i) {
    for (int j = 0; j < ag[i].size(); ++j) {
      int d = ag[i][j].dst;
      int s = ag[i][j].src;

      bool ok = false;
      for (int k = 0; k < ag[d].size(); ++k) {
        if (ag[d][k].src == s) {
          ok = true;
          break;
        }
      }
      if (!ok) {
        g[d].push_back(Edge(d, s, 0, -ag[i][j].cost));
      }
    }
  }
  const int n = g.size();
  Matrix capacity(n, Array(n)), cost(n, Array(n)), flow(n, Array(n));
  REP(u, n) FOR(e, g[u]) {
    capacity[e->src][e->dst] += e->capacity;
    cost[e->src][e->dst] += e->cost;
  }
  pair<Weight, Weight> total; // (cost, flow)
  vector<Weight> h(n);

  for (Weight F = L_INF; F > 0;) { // residual flow
    vector<Weight> d(n, L_INF);
    d[s] = 0;
    vector<int> p(n, -1);
    priority_queue<Edge> Q; // "e < f" <=> "e.cost > f.cost"
    for (Q.push(Edge(-2, s, 0, 0)); !Q.empty();) {
      Edge e = Q.top();
      Q.pop();
      if (p[e.dst] != -1)
        continue;
      p[e.dst] = e.src;
      FOR(f, g[e.dst]) if (RESIDUE(f->src, f->dst) > 0) {
        if (d[f->dst] > d[f->src] + RCOST(f->src, f->dst)) {
          d[f->dst] = d[f->src] + RCOST(f->src, f->dst);
          Q.push(Edge(f->src, f->dst, 0, d[f->dst]));
        }
      }
    }
    if (p[t] == -1)
      break;

    Weight f = F;
    for (int u = t; u != s; u = p[u])
      f = min(f, RESIDUE(p[u], u));
    for (int u = t; u != s; u = p[u]) {
      total.first += f * cost[p[u]][u];
      flow[p[u]][u] += f;
      flow[u][p[u]] -= f;
    }
    F -= f;
    total.second += f;
    REP(u, n) h[u] += d[u];
  }
  return total;
}
int main() {
  int N;
  cin >> N;
  vector<int> vs;
  vector<pair<long long int, long long int>> ps;
  for (int i = 0; i < N; ++i) {
    long long int a, b;
    cin >> a >> b;
    ps.emplace_back(a, b);
    vs.push_back(a);
    vs.push_back(b);
  }
  Compress cp(vs);

  const int start = 0;
  const int snode = start + 1;
  const int he = snode + N;
  const int goal = he + 2 * N;
  Graph g(goal + 1);
  for (int i = 0; i < N; ++i) {
    g[start].push_back(Edge(start, snode + i, 1, 0));
  }
  for (int i = 0; i < N; ++i) {
    g[snode + i].push_back(
        Edge(snode + i, he + cp.mp[ps[i].first], 1, 1000000 - ps[i].second));
    g[snode + i].push_back(
        Edge(snode + i, he + cp.mp[ps[i].second], 1, 1000000 - ps[i].first));
    g[snode + i].push_back(Edge(snode + i, goal, 1, 1000000));
  }
  for (int i = 0; i < 2 * N; ++i) {
    g[he + i].push_back(Edge(he + i, goal, 1, 0));
  }
  auto p = minimumCostFlow(g, start, goal);
  long long int ans = 1000000 * N - p.first;
  cout << ans << endl;
  return 0;
}