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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<P, int> pip;
typedef vector<pip> vip;
const int inf = 1 << 29;
const ll INF = 1ll << 50;
const double pi = acos(-1);
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

class Network {
private:
  int V;
  struct edge {
    int to, cap, cost, rev;
  };
  vector<vector<edge>> g;
  vi h, d, pv, pe;

public:
  Network(int v) {
    V = v;
    g = vector<vector<edge>>(v);
  }
  void add_edge(int s, int t, int cap, int cost) {
    g[s].push_back(edge{t, cap, cost, (int)g[t].size()});
    g[t].push_back(edge{s, 0, -cost, (int)g[s].size() - 1});
  }
  int min_cost_flow(int s, int t, int f) {
    int res = 0;
    h = pv = pe = vi(V);
    while (f > 0) {
      priority_queue<P> q;
      d = vi(V, inf);
      d[s] = 0;
      q.push({0, s});
      while (!q.empty()) {
        P p = q.top();
        q.pop();
        int v = p.second;
        if (d[v] < -p.first)
          continue;
        for (int i = 0; i < g[v].size(); i++) {
          edge &e = g[v][i];
          if (e.cap > 0 && d[e.to] > d[v] + e.cost + h[v] - h[e.to]) {
            d[e.to] = d[v] + e.cost + h[v] - h[e.to];
            pv[e.to] = v;
            pe[e.to] = i;
            q.push({-d[e.to], e.to});
          }
        }
      }
      if (d[t] == inf)
        return -1;
      for (int i = 0; i < V; i++)
        h[i] += d[i];
      int D = f;
      for (int i = t; i != s; i = pv[i])
        D = min(D, g[pv[i]][pe[i]].cap);
      f -= D;
      res += D * h[t];
      for (int i = t; i != s; i = pv[i]) {
        edge &e = g[pv[i]][pe[i]];
        e.cap -= D;
        g[i][e.rev].cap += D;
      }
    }
    return res;
  }
};

int n;
vi a, b;

int main() {
  cin >> n;
  a = b = vi(n);
  map<int, int> m;
  int S = 0, sum = 0;
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> b[i];
    sum += a[i] + b[i];
    if (m.find(a[i]) == m.end())
      m[a[i]] = S++;
    if (m.find(b[i]) == m.end())
      m[b[i]] = S++;
  }
  Network nt(n + S + 3);
  for (int i = 0; i < n; i++) {
    nt.add_edge(i + 1, n + m[a[i]] + 1, 1, a[i]);
    nt.add_edge(i + 1, n + m[b[i]] + 1, 1, b[i]);
    nt.add_edge(i + 1, n + S + 1, 1, a[i] + b[i]);
  }
  for (int i = 0; i < n; i++)
    nt.add_edge(0, i + 1, 1, 0);
  for (int i = 0; i < S; i++)
    nt.add_edge(n + i + 1, n + S + 2, 1, 0);
  nt.add_edge(n + S + 1, n + S + 2, inf, 0);
  cout << sum - nt.min_cost_flow(0, n + S + 2, n) << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<P, int> pip;
typedef vector<pip> vip;
const int inf = 1 << 29;
const ll INF = 1ll << 50;
const double pi = acos(-1);
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

class Network {
private:
  int V;
  struct edge {
    int to, cap, cost, rev;
  };
  vector<vector<edge>> g;
  vi h, d, pv, pe;

public:
  Network(int v) {
    V = v;
    g = vector<vector<edge>>(v);
  }
  void add_edge(int s, int t, int cap, int cost) {
    g[s].push_back(edge{t, cap, cost, (int)g[t].size()});
    g[t].push_back(edge{s, 0, -cost, (int)g[s].size() - 1});
  }
  int min_cost_flow(int s, int t, int f) {
    int res = 0;
    h = pv = pe = vi(V);
    while (f > 0) {
      priority_queue<P> q;
      d = vi(V, inf);
      d[s] = 0;
      q.push({0, s});
      while (!q.empty()) {
        P p = q.top();
        q.pop();
        int v = p.second;
        if (d[v] < -p.first)
          continue;
        for (int i = 0; i < g[v].size(); i++) {
          edge &e = g[v][i];
          if (e.cap > 0 && d[e.to] > d[v] + e.cost + h[v] - h[e.to]) {
            d[e.to] = d[v] + e.cost + h[v] - h[e.to];
            pv[e.to] = v;
            pe[e.to] = i;
            q.push({-d[e.to], e.to});
          }
        }
      }
      if (d[t] == inf)
        return -1;
      for (int i = 0; i < V; i++)
        h[i] += d[i];
      int D = f;
      for (int i = t; i != s; i = pv[i])
        D = min(D, g[pv[i]][pe[i]].cap);
      f -= D;
      res += D * h[t];
      for (int i = t; i != s; i = pv[i]) {
        edge &e = g[pv[i]][pe[i]];
        e.cap -= D;
        g[i][e.rev].cap += D;
      }
    }
    return res;
  }
};

const int M = 1000000;

int n;

int main() {
  cin >> n;
  Network nt(n + M + 3);
  int sum = 0;
  for (int i = 0; i < n; i++) {
    int A, B;
    cin >> A >> B;
    sum += A + B;
    nt.add_edge(i + 1, n + A, 1, A);
    nt.add_edge(i + 1, n + B, 1, B);
    nt.add_edge(i + 1, n + M + 1, 1, A + B);
  }
  for (int i = 1; i <= n; i++)
    nt.add_edge(0, i, 1, 0);
  for (int i = 0; i < M; i++)
    nt.add_edge(n + i + 1, n + M + 2, 1, 0);
  nt.add_edge(n + M + 1, n + M + 2, inf, 0);
  cout << sum - nt.min_cost_flow(0, n + M + 2, n) << endl;
}