Problem p03718 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)

using namespace std;

typedef long long LL;
typedef double db;

int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9')
      s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0';
  return s;
}

const int N = 110;
const int INF = 1E+9;

int H, W;
char mp[N][N];
struct edge {
  int x, nxt, f;
} e[N * N * 2];
int h[N * 2], tot, st, ed;
int dis[N * 2], que[N * 2];
bool pd[N * 2];

void addedge(int x, int y, int f) {
  e[++tot].x = y;
  e[tot].f = f;
  e[tot].nxt = h[x];
  h[x] = tot;
}

void inse(int x, int y, int f) { addedge(x, y, f), addedge(y, x, 0); }

bool bfs() {
  int he = 0, ta = 1;
  fo(i, st, ed) dis[i] = INF, pd[i] = 0;
  que[1] = st, pd[st] = 1, dis[st] = 0;
  for (; he != ta;) {
    int x = que[he = he % (ed + 1) + 1];
    pd[x] = 0;
    for (int p = h[x]; p; p = e[p].nxt)
      if (e[p].f && dis[e[p].x] == INF) {
        dis[e[p].x] = dis[x] + 1;
        if (!pd[e[p].x]) {
          pd[e[p].x] = 1;
          que[ta = ta % (ed + 1) + 1] = e[p].x;
        }
      }
  }
  return dis[ed] < INF;
}

int aug(int x, int f) {
  if (x == ed)
    return f;
  int ans = 0;
  for (int p = h[x]; p; p = e[p].nxt)
    if (e[p].f && dis[e[p].x] == dis[x] + 1) {
      int o = aug(e[p].x, min(f, e[p].f));
      f -= o, ans += o;
      e[p].f -= o, e[p ^ 1].f += o;
      if (!f)
        return ans;
    }
  return ans;
}

int main() {
  H = get();
  W = get();
  st = 0, ed = H + W + 1;
  tot = 1;
  fo(i, 1, H) {
    scanf("%s", mp[i] + 1);
    fo(j, 1, W) {
      if (mp[i][j] == 'S')
        inse(st, i, INF), inse(st, j + H, INF);
      if (mp[i][j] == 'T')
        inse(i, ed, INF), inse(j + H, ed, INF);
      if (mp[i][j] == 'o')
        inse(i, H + j, 1), inse(j + H, i, 1);
    }
  }
  int ans = 0;
  while (bfs())
    ans = ans + aug(st, INF);
  if (ans >= INF)
    ans = -1;
  printf("%d\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)

using namespace std;

typedef long long LL;
typedef double db;

int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9')
      s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0';
  return s;
}

const int N = 1010;
const int INF = 1E+9;

int H, W;
char mp[N][N];
struct edge {
  int x, nxt, f;
} e[N * N * 2];
int h[N * 2], tot, st, ed;
int dis[N * 2], que[N * 2];
bool pd[N * 2];

void addedge(int x, int y, int f) {
  e[++tot].x = y;
  e[tot].f = f;
  e[tot].nxt = h[x];
  h[x] = tot;
}

void inse(int x, int y, int f) { addedge(x, y, f), addedge(y, x, 0); }

bool bfs() {
  int he = 0, ta = 1;
  fo(i, st, ed) dis[i] = INF, pd[i] = 0;
  que[1] = st, pd[st] = 1, dis[st] = 0;
  for (; he != ta;) {
    int x = que[he = he % (ed + 1) + 1];
    pd[x] = 0;
    for (int p = h[x]; p; p = e[p].nxt)
      if (e[p].f && dis[e[p].x] == INF) {
        dis[e[p].x] = dis[x] + 1;
        if (!pd[e[p].x]) {
          pd[e[p].x] = 1;
          que[ta = ta % (ed + 1) + 1] = e[p].x;
        }
      }
  }
  return dis[ed] < INF;
}

int aug(int x, int f) {
  if (x == ed)
    return f;
  int ans = 0;
  for (int p = h[x]; p; p = e[p].nxt)
    if (e[p].f && dis[e[p].x] == dis[x] + 1) {
      int o = aug(e[p].x, min(f, e[p].f));
      f -= o, ans += o;
      e[p].f -= o, e[p ^ 1].f += o;
      if (!f)
        return ans;
    }
  return ans;
}

int main() {
  H = get();
  W = get();
  st = 0, ed = H + W + 1;
  tot = 1;
  fo(i, 1, H) {
    scanf("%s", mp[i] + 1);
    fo(j, 1, W) {
      if (mp[i][j] == 'S')
        inse(st, i, INF), inse(st, j + H, INF);
      if (mp[i][j] == 'T')
        inse(i, ed, INF), inse(j + H, ed, INF);
      if (mp[i][j] == 'o')
        inse(i, H + j, 1), inse(j + H, i, 1);
    }
  }
  int ans = 0;
  while (bfs())
    ans = ans + aug(st, INF);
  if (ans >= INF)
    ans = -1;
  printf("%d\n", ans);
  return 0;
}