Problem p03409 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <random>
#include <string.h>
#include <string>
#include <utility>
#include <vector>
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define rep(N) for (int i = 0; i < N; ++i)
#define Rep(a, b) for (int i = a; i < b; ++i)
#define For(i, N) for (int i = 0; i < N; ++i)
#define all(v) v.begin(), v.end()
#define rev(v) v.rbegin(), v.rend()
#define makei(N)                                                               \
  int N;                                                                       \
  cin >> N;
#define makel(N)                                                               \
  ll N;                                                                        \
  cin >> N;
#define makes(s)                                                               \
  string s;                                                                    \
  cin >> s;
#define maked(d)                                                               \
  double d;                                                                    \
  cin >> d;
#define makev(v, N)                                                            \
  vi v(N);                                                                     \
  rep(N) cin >> v[i];
#define mod 1000000007
#define re return 0

using namespace std;
using ll = long long int;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vs = vector<string>;
using pii = pair<int, int>;
using pis = pair<int, string>;
using msi = map<string, int>;

template <typename T> void say(T s) { cout << s << "\n"; }

template <typename T> void say(vector<T> s) {
  auto itr = s.begin();
  cout << *(itr++);
  while (itr != s.end()) {
    cout << " " << *(itr++);
  }
  cout << "\n";
}

void yn(bool b) {
  if (b)
    say("YES");
  else
    say("NO");
}

int N;
const int MAX_V = 100;
const int INF = 100000;
struct edge {
  int to, cap, rev;
};
vector<edge> G[MAX_V]; // グラフの隣接リスト表現
bool used[MAX_V];

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

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  rep(G[v].size()) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  while (true) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, INF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {
  cin >> N;
  vi a(N), b(N), c(N), d(N);
  rep(N) cin >> a[i] >> b[i];
  rep(N) cin >> c[i] >> d[i];
  int s = 2 * N;
  int t = s + 1;
  rep(N) add_edge(s, i, 1);
  rep(N) add_edge(N + i, t, 1);
  For(i, N) {
    For(j, N) {
      if (a[i] < c[j] && b[i] < d[j])
        add_edge(i, N + j, 1);
    }
  }
  say(max_flow(s, t));
}
/*
        0～N-1を赤、N～2N-1を青の点として二部マッチング
*/

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <random>
#include <string.h>
#include <string>
#include <utility>
#include <vector>
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define rep(N) for (int i = 0; i < N; ++i)
#define Rep(a, b) for (int i = a; i < b; ++i)
#define For(i, N) for (int i = 0; i < N; ++i)
#define all(v) v.begin(), v.end()
#define rev(v) v.rbegin(), v.rend()
#define makei(N)                                                               \
  int N;                                                                       \
  cin >> N;
#define makel(N)                                                               \
  ll N;                                                                        \
  cin >> N;
#define makes(s)                                                               \
  string s;                                                                    \
  cin >> s;
#define maked(d)                                                               \
  double d;                                                                    \
  cin >> d;
#define makev(v, N)                                                            \
  vi v(N);                                                                     \
  rep(N) cin >> v[i];
#define mod 1000000007
#define re return 0

using namespace std;
using ll = long long int;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vs = vector<string>;
using pii = pair<int, int>;
using pis = pair<int, string>;
using msi = map<string, int>;

template <typename T> void say(T s) { cout << s << "\n"; }

template <typename T> void say(vector<T> s) {
  auto itr = s.begin();
  cout << *(itr++);
  while (itr != s.end()) {
    cout << " " << *(itr++);
  }
  cout << "\n";
}

void yn(bool b) {
  if (b)
    say("YES");
  else
    say("NO");
}

int N;
const int MAX_V = 10000;
const int INF = 100000;
struct edge {
  int to, cap, rev;
};
vector<edge> G[MAX_V]; // グラフの隣接リスト表現
bool used[MAX_V];

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

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  rep(G[v].size()) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  while (true) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, INF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {
  cin >> N;
  vi a(N), b(N), c(N), d(N);
  rep(N) cin >> a[i] >> b[i];
  rep(N) cin >> c[i] >> d[i];
  int s = 2 * N;
  int t = s + 1;
  rep(N) add_edge(s, i, 1);
  rep(N) add_edge(N + i, t, 1);
  For(i, N) {
    For(j, N) {
      if (a[i] < c[j] && b[i] < d[j])
        add_edge(i, N + j, 1);
    }
  }
  say(max_flow(s, t));
}
/*
        0～N-1を赤、N～2N-1を青の点として二部マッチング
*/