Problem p02378 (C++)

Buggy submission (status: Runtime Error):
// this program solves bipartite matching using
// maximum flow algorithm

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>

const int N = 220;
const int M = 20010;

struct Edge {
  int to, cap, next;
} es[M];

int S, T;              // source, sink
int SIZE = 0;          // number of edges
int h[N];              // pointer to edge list
int dist[N], queue[N]; // for calculating shortest path

// add forward and backtracked edge
void add(int u, int v, int cap) {
  int i = SIZE++;
  es[i].to = v;
  es[i].cap = cap;
  es[i].next = h[u];
  h[u] = i;
  int j = SIZE++;
  es[j].to = u;
  es[j].cap = 0;
  es[j].next = h[v];
  h[v] = j;
}

// returns whether find a path from S to T
bool bfs() {
  int front = 0, back = 0;
  memset(dist, -1, sizeof(dist));
  queue[back++] = S;
  dist[S] = 0;
  while (front < back) {
    int x = queue[front++];
    for (int i = h[x]; i != -1; i = es[i].next)
      if (es[i].cap > 0) {
        int y = es[i].to;
        if (dist[y] == -1) {
          dist[y] = dist[x] + 1;
          queue[back++] = y;
        }
      }
    if (dist[T] != -1)
      return true;
  }
  return false;
}

// returns the flow pushed from x to T
int dfs(int x, int flow) {
  if (x == T)
    return flow;
  int dy = dist[x] + 1, ret = 0;
  for (int i = h[x]; i != -1 && flow > 0; i = es[i].next) {
    int y = es[i].to;
    if (dist[y] != dy)
      continue;
    int f = dfs(y, std::min(flow, es[i].cap));
    if (f != 0) {
      es[i].cap -= f;
      es[i ^ 1].cap += f;
      ret += f;
      flow -= f;
    }
  }
  if (flow > 0)
    dist[x] = -1;
  return ret;
}

void run() {
  int n1, n2, m, u, v;
  scanf("%d%d%d", &n1, &n2, &m);
  memset(h, -1, sizeof(h));
  S = 0, T = n1 + n2 + 1;
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    u++, v++;
    add(u, n1 + v, 1);
  }
  for (int i = 1; i <= n1; i++)
    add(S, i, 1);
  for (int i = 1; i <= n2; i++)
    add(n1 + i, T, 1);
  int flow = 0;
  while (bfs())
    flow += dfs(S, 0x3fffffff);
  printf("%d\n", flow);
}

int main() { run(); }

Fixed submission:
// this program solves bipartite matching using
// maximum flow algorithm

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>

const int N = 220;
const int M = 22000;

struct Edge {
  int to, cap, next;
} es[M];

int S, T;              // source, sink
int SIZE = 0;          // number of edges
int h[N];              // pointer to edge list
int dist[N], queue[N]; // for calculating shortest path

// add forward and backtracked edge
void add(int u, int v, int cap) {
  int i = SIZE++;
  es[i].to = v;
  es[i].cap = cap;
  es[i].next = h[u];
  h[u] = i;
  int j = SIZE++;
  es[j].to = u;
  es[j].cap = 0;
  es[j].next = h[v];
  h[v] = j;
}

// returns whether find a path from S to T
bool bfs() {
  int front = 0, back = 0;
  memset(dist, -1, sizeof(dist));
  queue[back++] = S;
  dist[S] = 0;
  while (front < back) {
    int x = queue[front++];
    for (int i = h[x]; i != -1; i = es[i].next)
      if (es[i].cap > 0) {
        int y = es[i].to;
        if (dist[y] == -1) {
          dist[y] = dist[x] + 1;
          queue[back++] = y;
        }
      }
    if (dist[T] != -1)
      return true;
  }
  return false;
}

// returns the flow pushed from x to T
int dfs(int x, int flow) {
  if (x == T)
    return flow;
  int dy = dist[x] + 1, ret = 0;
  for (int i = h[x]; i != -1 && flow > 0; i = es[i].next) {
    int y = es[i].to;
    if (dist[y] != dy)
      continue;
    int f = dfs(y, std::min(flow, es[i].cap));
    if (f != 0) {
      es[i].cap -= f;
      es[i ^ 1].cap += f;
      ret += f;
      flow -= f;
    }
  }
  if (flow > 0)
    dist[x] = -1;
  return ret;
}

void run() {
  int n1, n2, m, u, v;
  scanf("%d%d%d", &n1, &n2, &m);
  memset(h, -1, sizeof(h));
  S = 0, T = n1 + n2 + 1;
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    u++, v++;
    add(u, n1 + v, 1);
  }
  for (int i = 1; i <= n1; i++)
    add(S, i, 1);
  for (int i = 1; i <= n2; i++)
    add(n1 + i, T, 1);
  int flow = 0;
  while (bfs())
    flow += dfs(S, 0x3fffffff);
  printf("%d\n", flow);
}

int main() { run(); }