Problem p01410 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#define reep(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, n) reep((i), 0, (n))

template <class T> class MinCostFlow {
public:
  class edge {
  public:
    int to;
    int capacity;
    T cost;
    int reve;

    edge(int _to, int _capacity, int _reve, T _cost) {
      this->to = _to;
      this->capacity = _capacity;
      this->reve = _reve;
      this->cost = _cost;
    }
  };
  static const int MV = 2010;
  vector<edge> E[MV];
  T dist[MV];
  int prev_v[MV], prev_e[MV], NV;

  MinCostFlow() { init(MV); }
  void init(int NV = MV) {
    this->NV = NV;
    for (int i = 0; i < MV; i++) {
      E[i].clear();
    }
  }
  void addEdge(int x, int y, int cap, T cost) {
    E[x].push_back(edge(y, cap, E[y].size(), cost));
    E[y].push_back(edge(x, 0, E[x].size() - 1, -cost));
  }
  T minCost(int from, int to, int flow) {
    T res = 0;
    T inf = std::numeric_limits<T>::max() / 2;
    memset(prev_v, 0, sizeof(prev_v));
    memset(prev_e, 0, sizeof(prev_e));
    while (flow > 0) {
      fill(dist, dist + NV, inf);
      dist[from] = 0;
      bool up = true;
      while (up) {
        up = false;
        for (int v = 0; v < NV; ++v) {
          if (dist[v] == inf)
            continue;
          for (int i = 0; i < E[v].size(); ++i) {
            edge &e = E[v][i];
            if (e.capacity > 0 && dist[e.to] > dist[v] + e.cost) {
              dist[e.to] = dist[v] + e.cost;
              prev_v[e.to] = v;
              prev_e[e.to] = i;
              up = true;
            }
          }
        }
      }
      if (dist[to] == inf)
        return -1;
      int lc = flow;
      for (int v = to; v != from; v = prev_v[v]) {
        lc = min(lc, E[prev_v[v]][prev_e[v]].capacity);
      }
      flow -= lc;
      res += lc * dist[to];
      for (int v = to; v != from; v = prev_v[v]) {
        edge &e = E[prev_v[v]][prev_e[v]];
        e.capacity -= lc;
        E[v][e.reve].capacity += lc;
      }
    }
    return res;
  }
};

MinCostFlow<int> mf;

int main() {
  int n;
  cin >> n;
  vector<int> a(n), b(n);
  map<int, int> ma;
  rep(i, n) {
    cin >> a[i] >> b[i];
    int ta;
    ta = ma.size();
    if (ma.count(a[i]) == 0)
      ma[a[i]] = ta;
    ta = ma.size();
    if (ma.count(b[i]) == 0)
      ma[b[i]] = ta;
  }
  int m = ma.size();
  int source = n + m;
  int sink = n + m + 1;
  int MA = 1000000;
  rep(i, n) {
    mf.addEdge(source, i, 1, 0);
    mf.addEdge(i, n + ma[a[i]], 1, MA - b[i]);
    mf.addEdge(i, n + ma[b[i]], 1, MA - a[i]);
  }
  for (auto x : ma) {
    mf.addEdge(n + x.second, sink, 1, 0);
  }
  mf.addEdge(source, sink, n, MA);
  long long ans = mf.minCost(source, sink, n);
  int t = n - mf.E[source].back().capacity;
  // ans-=t*MA;
  ans -= (n)*MA;
  ans *= -1;
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define reep(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, n) reep((i), 0, (n))

template <class T> class MinCostFlow {
public:
  class edge {
  public:
    int to;
    int capacity;
    T cost;
    int reve;

    edge(int _to, int _capacity, int _reve, T _cost) {
      this->to = _to;
      this->capacity = _capacity;
      this->reve = _reve;
      this->cost = _cost;
    }
  };
  static const int MV = 3010;
  vector<edge> E[MV];
  T dist[MV];
  int prev_v[MV], prev_e[MV], NV;

  MinCostFlow() { init(MV); }
  void init(int NV = MV) {
    this->NV = NV;
    for (int i = 0; i < MV; i++) {
      E[i].clear();
    }
  }
  void addEdge(int x, int y, int cap, T cost) {
    E[x].push_back(edge(y, cap, E[y].size(), cost));
    E[y].push_back(edge(x, 0, E[x].size() - 1, -cost));
  }
  T minCost(int from, int to, int flow) {
    T res = 0;
    T inf = std::numeric_limits<T>::max() / 2;
    memset(prev_v, 0, sizeof(prev_v));
    memset(prev_e, 0, sizeof(prev_e));
    while (flow > 0) {
      fill(dist, dist + NV, inf);
      dist[from] = 0;
      bool up = true;
      while (up) {
        up = false;
        for (int v = 0; v < NV; ++v) {
          if (dist[v] == inf)
            continue;
          for (int i = 0; i < E[v].size(); ++i) {
            edge &e = E[v][i];
            if (e.capacity > 0 && dist[e.to] > dist[v] + e.cost) {
              dist[e.to] = dist[v] + e.cost;
              prev_v[e.to] = v;
              prev_e[e.to] = i;
              up = true;
            }
          }
        }
      }
      if (dist[to] == inf)
        return -1;
      int lc = flow;
      for (int v = to; v != from; v = prev_v[v]) {
        lc = min(lc, E[prev_v[v]][prev_e[v]].capacity);
      }
      flow -= lc;
      res += lc * dist[to];
      for (int v = to; v != from; v = prev_v[v]) {
        edge &e = E[prev_v[v]][prev_e[v]];
        e.capacity -= lc;
        E[v][e.reve].capacity += lc;
      }
    }
    return res;
  }
};

MinCostFlow<int> mf;

int main() {
  int n;
  cin >> n;
  vector<int> a(n), b(n);
  map<int, int> ma;
  rep(i, n) {
    cin >> a[i] >> b[i];
    int ta;
    ta = ma.size();
    if (ma.count(a[i]) == 0)
      ma[a[i]] = ta;
    ta = ma.size();
    if (ma.count(b[i]) == 0)
      ma[b[i]] = ta;
  }
  int m = ma.size();
  int source = n + m;
  int sink = n + m + 1;
  int MA = 1000000;
  rep(i, n) {
    mf.addEdge(source, i, 1, 0);
    mf.addEdge(i, n + ma[a[i]], 1, MA - b[i]);
    mf.addEdge(i, n + ma[b[i]], 1, MA - a[i]);
  }
  for (auto x : ma) {
    mf.addEdge(n + x.second, sink, 1, 0);
  }
  mf.addEdge(source, sink, n, MA);
  long long ans = mf.minCost(source, sink, n);
  int t = n - mf.E[source].back().capacity;
  // ans-=t*MA;
  ans -= (n)*MA;
  ans *= -1;
  cout << ans << endl;
}