Problem p03718 (C++)

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

const int MAXN = 110 * 110 * 2;
const int INF = std::numeric_limits<int>::max();
const int MAXM = MAXN * 10;
int head[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot = 1;
int S, T, idx;
void addedge(int b, int e, int v) {
  nxt[++tot] = head[b];
  to[head[b] = tot] = e;
  val[tot] = v;
  nxt[++tot] = head[e];
  to[head[e] = tot] = b;
  val[tot] = 0;
}
int dis[MAXN];
std::queue<int> q;
bool bfs() {
  memset(dis, 0, idx + 1 << 2);
  q.push(S);
  dis[S] = 1;
  while (!q.empty()) {
    int t = q.front();
    q.pop();
    for (int i = head[t]; i; i = nxt[i])
      if (val[i] && !dis[to[i]]) {
        q.push(to[i]);
        dis[to[i]] = dis[t] + 1;
      }
  }
  return dis[T] > 0;
}
int dinic(int u, int minv) {
  if (!minv || u == T)
    return minv;
  int res = 0, t;
  for (int &i = head[u]; i; i = nxt[i])
    if (val[i] && dis[to[i]] == dis[u] + 1 &&
        (t = dinic(to[i], std::min(minv, val[i])))) {
      val[i] -= t;
      val[i ^ 1] += t;
      res += t;
      minv -= t;
      if (!minv)
        break;
    }
  if (!res)
    dis[u] = -1;
  return res;
}
int tmp;
int flow() {
  static int te[MAXN];
  int ans = 0;
  memcpy(te, head, idx + 1 << 2);
  while (bfs()) {
    ans += dinic(S, INF);
    if (ans > tmp)
      break;
    memcpy(head, te, idx + 1 << 2);
  }
  return ans;
}
int in[110][110], out[110][110];
char mat[110][110];
int main() {
  std::ios_base::sync_with_stdio(false), std::cin.tie(0);
  int H, W;
  std::cin >> H >> W;
  S = idx, T = ++idx;
  for (int i = 1; i <= H; ++i) {
    std::cin >> mat[i] + 1;
    for (int j = 1; j <= W; ++j)
      if (mat[i][j] != '.') {
        in[i][j] = ++idx, out[i][j] = ++idx;
        addedge(in[i][j], out[i][j], mat[i][j] == 'o' ? 1 : INF);
        if (mat[i][j] == 'S')
          addedge(S, in[i][j], INF);
        if (mat[i][j] == 'T')
          addedge(out[i][j], T, INF);
        tmp += mat[i][j] == 'o';
      }
  }
  for (int i = 1; i <= H; ++i)
    for (int j = 1; j <= W; ++j)
      if (mat[i][j] != '.') {
        for (int k = 1; k <= W; ++k)
          if (mat[i][k] != '.')
            addedge(out[i][j], in[i][k], INF);
        for (int k = 1; k <= H; ++k)
          if (mat[k][j] != '.')
            addedge(out[i][j], in[k][j], INF);
      }
  int ans = flow();
  if (ans > tmp)
    ans = -1;
  std::cout << ans << std::endl;
  return 0;
}


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

const int MAXN = 110 * 110 * 2;
const int INF = std::numeric_limits<int>::max();
const int MAXM = MAXN * 110 * 10;
int head[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot = 1;
int S, T, idx;
void addedge(int b, int e, int v) {
  nxt[++tot] = head[b];
  to[head[b] = tot] = e;
  val[tot] = v;
  nxt[++tot] = head[e];
  to[head[e] = tot] = b;
  val[tot] = 0;
}
int dis[MAXN];
std::queue<int> q;
bool bfs() {
  memset(dis, 0, idx + 1 << 2);
  q.push(S);
  dis[S] = 1;
  while (!q.empty()) {
    int t = q.front();
    q.pop();
    for (int i = head[t]; i; i = nxt[i])
      if (val[i] && !dis[to[i]]) {
        q.push(to[i]);
        dis[to[i]] = dis[t] + 1;
      }
  }
  return dis[T] > 0;
}
int dinic(int u, int minv) {
  if (!minv || u == T)
    return minv;
  int res = 0, t;
  for (int &i = head[u]; i; i = nxt[i])
    if (val[i] && dis[to[i]] == dis[u] + 1 &&
        (t = dinic(to[i], std::min(minv, val[i])))) {
      val[i] -= t;
      val[i ^ 1] += t;
      res += t;
      minv -= t;
      if (!minv)
        break;
    }
  if (!res)
    dis[u] = -1;
  return res;
}
int tmp;
int flow() {
  static int te[MAXN];
  int ans = 0;
  memcpy(te, head, idx + 1 << 2);
  while (bfs()) {
    ans += dinic(S, INF);
    if (ans > tmp)
      break;
    memcpy(head, te, idx + 1 << 2);
  }
  return ans;
}
int in[110][110], out[110][110];
char mat[110][110];
int main() {
  std::ios_base::sync_with_stdio(false), std::cin.tie(0);
  int H, W;
  std::cin >> H >> W;
  S = idx, T = ++idx;
  for (int i = 1; i <= H; ++i) {
    std::cin >> mat[i] + 1;
    for (int j = 1; j <= W; ++j)
      if (mat[i][j] != '.') {
        in[i][j] = ++idx, out[i][j] = ++idx;
        addedge(in[i][j], out[i][j], mat[i][j] == 'o' ? 1 : INF);
        if (mat[i][j] == 'S')
          addedge(S, in[i][j], INF);
        if (mat[i][j] == 'T')
          addedge(out[i][j], T, INF);
        tmp += mat[i][j] == 'o';
      }
  }
  for (int i = 1; i <= H; ++i)
    for (int j = 1; j <= W; ++j)
      if (mat[i][j] != '.') {
        for (int k = 1; k <= W; ++k)
          if (mat[i][k] != '.')
            addedge(out[i][j], in[i][k], INF);
        for (int k = 1; k <= H; ++k)
          if (mat[k][j] != '.')
            addedge(out[i][j], in[k][j], INF);
      }
  int ans = flow();
  if (ans > tmp)
    ans = -1;
  std::cout << ans << std::endl;
  return 0;
}