Problem p03718 (C++)

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

const int N = 108;

namespace Flow {
#define ad(x) ((x - 1 ^ 1) + 1)

const int N = 40000, M = 100000;

struct edge {
  int u, v, f;
  edge(int u0 = 0, int v0 = 0, int f0 = 0) : u(u0), v(v0), f(f0) {}
} e[M];

int V = 2, E = 0, si = 1, ti = 2, flow;
int first[N], next[M];
int dep[N], cur[N], que[N];

inline void addedge(int u, int v, int f) {
  e[++E] = edge(u, v, f), next[E] = first[u], first[u] = E;
  e[++E] = edge(v, u), next[E] = first[v], first[v] = E;
}

bool bfs() {
  int h, t = 1, i, x, y;
  memset(dep, -1, sizeof dep);
  que[0] = si, dep[si] = 0;
  for (h = 0; h < t; h++) {
    if ((x = que[h]) == ti)
      return true;
    for (i = first[x]; i; i = next[i])
      if (dep[y = e[i].v] == -1 && e[i].f)
        que[t++] = y, dep[y] = dep[x] + 1;
  }
  return false;
}

int dfs(int x, int lim) {
  int a, c, f = 0;
  if (x == ti || !lim)
    return lim;
  for (int &i = cur[x]; i; i = next[i])
    if (dep[e[i].v] == dep[x] + 1 && e[i].f) {
      a = std::min(lim - f, e[i].f);
      c = dfs(e[i].v, a);
      e[i].f -= c;
      e[ad(i)].f += c;
      if ((f += c) == lim)
        return f;
    }
  return f;
}

int Dinic() {
  for (flow = 0; bfs(); flow += dfs(si, INT_MAX))
    memcpy(cur, first, sizeof cur);
  return flow;
}
} // namespace Flow

int R, C, sr, sc, tr, tc;
int in[N][N], out[N][N];
char map[N][N];

int main() {
  int i, j, &n = Flow::V;
  scanf("%d%d", &R, &C);
  for (i = 0; i < R; ++i)
    for (scanf("%s", map[i]), j = 0; j < C; ++j)
      if (map[i][j] == 83)
        sr = i, sc = j;
      else if (map[i][j] == 84)
        tr = i, tc = j;
  if (sr == tr || sc == tc)
    return puts("-1"), 0;
  n = 2 + R + C;
  for (i = 0; i < R; ++i)
    for (j = 0; j < C; ++j)
      if (map[i][j] == 111)
        in[i][j] = ++n, out[i][j] = ++n,
        Flow::addedge(3 + i, in[i][j], INT_MAX),
        Flow::addedge(3 + R + j, in[i][j], INT_MAX),
        Flow::addedge(in[i][j], out[i][j], 1),
        Flow::addedge(out[i][j], 3 + i, INT_MAX),
        Flow::addedge(out[i][j], 3 + R + j, INT_MAX),
        Flow::addedge(1, 3 + sr, INT_MAX),
        Flow::addedge(1, 3 + R + sc, INT_MAX),
        Flow::addedge(3 + tr, 2, INT_MAX),
        Flow::addedge(3 + R + tc, 2, INT_MAX);
  printf("%d\n", Flow::Dinic());
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

const int N = 108;

namespace Flow {
#define ad(x) ((x - 1 ^ 1) + 1)

const int N = 40000, M = 200000;

struct edge {
  int u, v, f;
  edge(int u0 = 0, int v0 = 0, int f0 = 0) : u(u0), v(v0), f(f0) {}
} e[M];

int V = 2, E = 0, si = 1, ti = 2, flow;
int first[N], next[M];
int dep[N], cur[N], que[N];

inline void addedge(int u, int v, int f) {
  e[++E] = edge(u, v, f), next[E] = first[u], first[u] = E;
  e[++E] = edge(v, u), next[E] = first[v], first[v] = E;
}

bool bfs() {
  int h, t = 1, i, x, y;
  memset(dep, -1, sizeof dep);
  que[0] = si, dep[si] = 0;
  for (h = 0; h < t; h++) {
    if ((x = que[h]) == ti)
      return true;
    for (i = first[x]; i; i = next[i])
      if (dep[y = e[i].v] == -1 && e[i].f)
        que[t++] = y, dep[y] = dep[x] + 1;
  }
  return false;
}

int dfs(int x, int lim) {
  int a, c, f = 0;
  if (x == ti || !lim)
    return lim;
  for (int &i = cur[x]; i; i = next[i])
    if (dep[e[i].v] == dep[x] + 1 && e[i].f) {
      a = std::min(lim - f, e[i].f);
      c = dfs(e[i].v, a);
      e[i].f -= c;
      e[ad(i)].f += c;
      if ((f += c) == lim)
        return f;
    }
  return f;
}

int Dinic() {
  for (flow = 0; bfs(); flow += dfs(si, INT_MAX))
    memcpy(cur, first, sizeof cur);
  return flow;
}
} // namespace Flow

int R, C, sr, sc, tr, tc;
int in[N][N], out[N][N];
char map[N][N];

int main() {
  int i, j, &n = Flow::V;
  scanf("%d%d", &R, &C);
  for (i = 0; i < R; ++i)
    for (scanf("%s", map[i]), j = 0; j < C; ++j)
      if (map[i][j] == 83)
        sr = i, sc = j;
      else if (map[i][j] == 84)
        tr = i, tc = j;
  if (sr == tr || sc == tc)
    return puts("-1"), 0;
  n = 2 + R + C;
  for (i = 0; i < R; ++i)
    for (j = 0; j < C; ++j)
      if (map[i][j] == 111)
        in[i][j] = ++n, out[i][j] = ++n,
        Flow::addedge(3 + i, in[i][j], INT_MAX),
        Flow::addedge(3 + R + j, in[i][j], INT_MAX),
        Flow::addedge(in[i][j], out[i][j], 1),
        Flow::addedge(out[i][j], 3 + i, INT_MAX),
        Flow::addedge(out[i][j], 3 + R + j, INT_MAX),
        Flow::addedge(1, 3 + sr, INT_MAX),
        Flow::addedge(1, 3 + R + sc, INT_MAX),
        Flow::addedge(3 + tr, 2, INT_MAX),
        Flow::addedge(3 + R + tc, 2, INT_MAX);
  printf("%d\n", Flow::Dinic());
  return 0;
}