Problem p01410 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define int long long
#define range(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

const int vmax = 1001;
const int inf = 1 << 29;
struct edge {
  int to, cap, cost, rev;
};
vector<edge> graph[vmax];

int h[vmax], dist[vmax];
int pv[vmax], pe[vmax];
typedef tuple<int, int> state;

void add_edge(int from, int to, int cap, int cost) {
  graph[from].push_back({to, cap, cost, (int)graph[to].size()});
  graph[to].push_back({from, 0, -cost, (int)graph[from].size() - 1});
}

int min_cost_flow(int s, int t, int f, int n) {
  int res = 0;
  fill(h, h + n, 0);
  while (f > 0) {
    priority_queue<state, vector<state>, greater<state>> q;
    fill(dist, dist + n, inf);
    dist[s] = 0;
    q.push(state(0, s));
    while (!q.empty()) {
      int cost, v;
      tie(cost, v) = q.top();
      q.pop();
      if (dist[v] < cost)
        continue;
      rep(i, graph[v].size()) {
        edge &e = graph[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          pv[e.to] = v, pe[e.to] = i;
          q.push(state(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == inf)
      return -1;
    rep(v, n) h[v] += dist[v];

    int d = f;
    for (int v = t; v != s; v = pv[v])
      d = min(d, graph[pv[v]][pe[v]].cap);
    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = pv[v]) {
      edge &e = graph[pv[v]][pe[v]];
      e.cap -= d;
      graph[v][e.rev].cap += d;
    }
  }
  return res;
}

signed main(void) {
  int n;
  cin >> n;
  vector<pair<int, int>> rects(n);
  int idx = n;
  map<int, int> l2i;
  for (auto &e : rects) {
    int a, b;
    cin >> a >> b;
    e = make_pair(a, b);

    if (l2i.find(a) == end(l2i))
      l2i[a] = idx++;
    if (l2i.find(b) == end(l2i))
      l2i[b] = idx++;
  }

  int dummy = idx++, s = idx++, t = idx++;

  rep(i, n) { add_edge(s, i, 1, 0); }
  range(i, n, dummy) { add_edge(i, t, 1, 0); }
  add_edge(dummy, t, inf, 0);

  rep(i, n) {
    add_edge(i, l2i[rects[i].first], 1, -rects[i].second);
    add_edge(i, l2i[rects[i].second], 1, -rects[i].first);
    add_edge(i, dummy, 1, 0);
  }

  cout << -min_cost_flow(s, t, n, idx) << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define int long long
#define range(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

const int vmax = 10001;
const int inf = 1 << 29;
struct edge {
  int to, cap, cost, rev;
};
vector<edge> graph[vmax];

int h[vmax], dist[vmax];
int pv[vmax], pe[vmax];
typedef tuple<int, int> state;

void add_edge(int from, int to, int cap, int cost) {
  graph[from].push_back({to, cap, cost, (int)graph[to].size()});
  graph[to].push_back({from, 0, -cost, (int)graph[from].size() - 1});
}

int min_cost_flow(int s, int t, int f, int n) {
  int res = 0;
  fill(h, h + n, 0);
  while (f > 0) {
    priority_queue<state, vector<state>, greater<state>> q;
    fill(dist, dist + n, inf);
    dist[s] = 0;
    q.push(state(0, s));
    while (!q.empty()) {
      int cost, v;
      tie(cost, v) = q.top();
      q.pop();
      if (dist[v] < cost)
        continue;
      rep(i, graph[v].size()) {
        edge &e = graph[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          pv[e.to] = v, pe[e.to] = i;
          q.push(state(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == inf)
      return -1;
    rep(v, n) h[v] += dist[v];

    int d = f;
    for (int v = t; v != s; v = pv[v])
      d = min(d, graph[pv[v]][pe[v]].cap);
    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = pv[v]) {
      edge &e = graph[pv[v]][pe[v]];
      e.cap -= d;
      graph[v][e.rev].cap += d;
    }
  }
  return res;
}

signed main(void) {
  int n;
  cin >> n;
  vector<pair<int, int>> rects(n);
  int idx = n;
  map<int, int> l2i;
  for (auto &e : rects) {
    int a, b;
    cin >> a >> b;
    e = make_pair(a, b);

    if (l2i.find(a) == end(l2i))
      l2i[a] = idx++;
    if (l2i.find(b) == end(l2i))
      l2i[b] = idx++;
  }

  int dummy = idx++, s = idx++, t = idx++;

  rep(i, n) { add_edge(s, i, 1, 0); }
  range(i, n, dummy) { add_edge(i, t, 1, 0); }
  add_edge(dummy, t, inf, 0);

  rep(i, n) {
    add_edge(i, l2i[rects[i].first], 1, -rects[i].second);
    add_edge(i, l2i[rects[i].second], 1, -rects[i].first);
    add_edge(i, dummy, 1, 0);
  }

  cout << -min_cost_flow(s, t, n, idx) << endl;

  return 0;
}