Problem p03718 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define N 20005
#define M 2000005
using namespace std;
int head[N], nxt[M], ver[M], tot, f[M];
void add(int a, int b, int c) {
  tot++;
  nxt[tot] = head[a];
  head[a] = tot;
  ver[tot] = b;
  f[tot] = c;
  tot++;
  nxt[tot] = head[b];
  head[b] = tot;
  ver[tot] = a;
  f[tot] = 0;
}
int S, T;
int ch[N];
int zeng(int a, int b) {
  if (a == T)
    return b;
  int r = 0;
  for (int i = head[a]; i && b > r; i = nxt[i]) {
    if (ch[ver[i]] == ch[a] + 1 && f[i]) {
      int t = zeng(ver[i], min(b - r, f[i]));
      r += t;
      f[i] -= t;
      f[i ^ 1] += t;
    }
  }
  if (!r)
    ch[a] = -1;
  return r;
}
bool tell() {
  memset(ch, -1, sizeof(ch));
  ch[S] = 0;
  queue<int> q;
  q.push(S);
  while (!q.empty()) {

    int tmp = q.front();
    q.pop();
    // cout<<tmp<<endl;
    for (int i = head[tmp]; i; i = nxt[i]) {
      if (f[i] && ch[ver[i]] == -1) {
        ch[ver[i]] = ch[tmp] + 1;
        q.push(ver[i]);
      }
    }
  }
  return ch[T] != -1;
}
int dinic() {
  int r = 0, t;
  while (tell())
    while (t = zeng(S, inf))
      r += t;
  return r;
}
int h, w, sm;
char s[105][105];
int Q(int x, int y) { return (x - 1) * w + y; }
int main() {
  tot = 1;
  scanf("%d%d", &h, &w);
  sm = h * w;
  for (int i = 1; i <= h; i++)
    scanf("%s", s[i] + 1);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (s[i][j] == '.')
        continue;
      if (s[i][j] == 'S')
        S = Q(i, j);
      if (s[i][j] == 'T')
        T = Q(i, j) + sm;
      for (int l = 1; l <= h; l++) {
        if (l == i)
          continue;
        add(Q(i, j) + sm, Q(l, j), inf);
      }
      for (int l = 1; l <= w; l++) {
        if (l == j)
          continue;
        add(Q(i, j) + sm, Q(i, l), inf);
      }
    }
  }
  for (int i = 1; i <= sm; i++) {
    if (i == S || i + sm == T)
      add(i, i + sm, inf);
    else
      add(i, i + sm, 1);
  }
  int ans = dinic();
  if (ans >= inf)
    puts("-1");
  else
    printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define N 20005
#define M 4000005
using namespace std;
int head[N], nxt[M], ver[M], tot, f[M];
void add(int a, int b, int c) {
  tot++;
  nxt[tot] = head[a];
  head[a] = tot;
  ver[tot] = b;
  f[tot] = c;
  tot++;
  nxt[tot] = head[b];
  head[b] = tot;
  ver[tot] = a;
  f[tot] = 0;
}
int S, T;
int ch[N];
int zeng(int a, int b) {
  if (a == T)
    return b;
  int r = 0;
  for (int i = head[a]; i && b > r; i = nxt[i]) {
    if (ch[ver[i]] == ch[a] + 1 && f[i]) {
      int t = zeng(ver[i], min(b - r, f[i]));
      r += t;
      f[i] -= t;
      f[i ^ 1] += t;
    }
  }
  if (!r)
    ch[a] = -1;
  return r;
}
bool tell() {
  memset(ch, -1, sizeof(ch));
  ch[S] = 0;
  queue<int> q;
  q.push(S);
  while (!q.empty()) {

    int tmp = q.front();
    q.pop();
    // cout<<tmp<<endl;
    for (int i = head[tmp]; i; i = nxt[i]) {
      if (f[i] && ch[ver[i]] == -1) {
        ch[ver[i]] = ch[tmp] + 1;
        q.push(ver[i]);
      }
    }
  }
  return ch[T] != -1;
}
int dinic() {
  int r = 0, t;
  while (tell())
    while (t = zeng(S, inf))
      r += t;
  return r;
}
int h, w, sm;
char s[105][105];
int Q(int x, int y) { return (x - 1) * w + y; }
int main() {
  tot = 1;
  scanf("%d%d", &h, &w);
  sm = h * w;
  for (int i = 1; i <= h; i++)
    scanf("%s", s[i] + 1);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (s[i][j] == '.')
        continue;
      if (s[i][j] == 'S')
        S = Q(i, j);
      if (s[i][j] == 'T')
        T = Q(i, j) + sm;
      for (int l = 1; l <= h; l++) {
        if (l == i)
          continue;
        add(Q(i, j) + sm, Q(l, j), inf);
      }
      for (int l = 1; l <= w; l++) {
        if (l == j)
          continue;
        add(Q(i, j) + sm, Q(i, l), inf);
      }
    }
  }
  for (int i = 1; i <= sm; i++) {
    if (i == S || i + sm == T)
      add(i, i + sm, inf);
    else
      add(i, i + sm, 1);
  }
  int ans = dinic();
  if (ans >= inf)
    puts("-1");
  else
    printf("%d\n", ans);
  return 0;
}