Problem p03718 (C++)

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

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;

#define REP(i, n) for (ll(i) = 0; (i) < (ll)(n); ++(i))
#define REPN(i, m, n) for (int(i) = m; (i) < (int)(n); ++(i))
#define REP_REV(i, n) for (int(i) = (int)(n)-1; (i) >= 0; --(i))
#define REPN_REV(i, m, n) for (int(i) = (int)(n)-1; (i) >= m; --(i))
#define ALL(x) x.begin(), x.end()

#define INF (1e10)
#define MOD (1000000007)

#define print2D(h, w, arr)                                                     \
  REP(i, h) {                                                                  \
    REP(j, w) cout << arr[i][j] << " ";                                        \
    cout << endl;                                                              \
  }
template <class T> void print(const T &x) {
  cout << setprecision(16) << x << endl;
}
template <class T, class... A> void print(const T &first, const A &...rest) {
  cout << first << " ";
  print(rest...);
}
struct PreMain {
  PreMain() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} premain;

#define MAX_V (100)
#define MAX_V2 (MAX_V * MAX_V)

struct edge {
  ll to;
  ll cap;
  ll rev;
};

vector<edge> G[MAX_V2 + 10];
bool used[MAX_V2 + 10];

void append_edge(ll from, ll to, ll cap) {
  G[from].emplace_back(edge{to, cap, (ll)G[to].size()});
  G[to].emplace_back(edge{from, 0, (ll)G[from].size() - 1});
}

int dfs(ll v, ll t, ll f) {
  if (v == t)
    return f;
  used[v] = true;
  for (ll i = 0; i < G[v].size(); i++) {
    auto &e = G[v][i];
    if (!used[e.to] && (0 < e.cap)) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (0 < d) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(ll s, ll t) {
  ll flow = 0;
  for (;;) {
    memset(used, 0, sizeof(used));
    ll f = dfs(s, t, numeric_limits<ll>::max());
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {
  int H, W;
  cin >> H >> W;

  vector<string> S(H);
  ll source = 0;
  ll sink = 0;

  REP(h, H) {
    cin >> S[h];
    REP(w, W) {
      switch (S[h][w]) {
      case 'S':
        source = h * MAX_V + w;
        S[h][w] = 'o';
        break;
      case 'T':
        sink = h * MAX_V + w + MAX_V2;
        S[h][w] = 'o';
        break;
      case 'o':
        break;
      default:
        continue;
      }
      append_edge(h * MAX_V + w + MAX_V2, h * MAX_V + w, 1);
      append_edge(h * MAX_V + w, h * MAX_V + w + MAX_V2, 1);
    }
  }

  REP(h, H) {
    REP(w, W) REP(w2, w) {
      if ((S[h][w] == 'o') && (S[h][w2] == 'o')) {
        append_edge(h * MAX_V + w, h * MAX_V + w2 + MAX_V2, 100001);
        append_edge(h * MAX_V + w2, h * MAX_V + w + MAX_V2, 100001);
      }
    }
  }

  REP(w, W) {
    REP(h, H) REP(h2, h) {
      if ((S[h][w] == 'o') && (S[h2][w] == 'o')) {
        append_edge(h * MAX_V + w, h2 * MAX_V + w + MAX_V2, 100001);
        append_edge(h2 * MAX_V + w, h * MAX_V + w + MAX_V2, 100001);
      }
    }
  }

  int ret = max_flow(source, sink);

  if ((MAX_V2) < ret) {
    ret = -1;
  }

  print(ret);

  return 0;
}


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

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;

#define REP(i, n) for (ll(i) = 0; (i) < (ll)(n); ++(i))
#define REPN(i, m, n) for (int(i) = m; (i) < (int)(n); ++(i))
#define REP_REV(i, n) for (int(i) = (int)(n)-1; (i) >= 0; --(i))
#define REPN_REV(i, m, n) for (int(i) = (int)(n)-1; (i) >= m; --(i))
#define ALL(x) x.begin(), x.end()

#define INF (1e10)
#define MOD (1000000007)

#define print2D(h, w, arr)                                                     \
  REP(i, h) {                                                                  \
    REP(j, w) cout << arr[i][j] << " ";                                        \
    cout << endl;                                                              \
  }
template <class T> void print(const T &x) {
  cout << setprecision(16) << x << endl;
}
template <class T, class... A> void print(const T &first, const A &...rest) {
  cout << first << " ";
  print(rest...);
}
struct PreMain {
  PreMain() {
    cin.tie(0);
    ios::sync_with_stdio(false);
  }
} premain;

#define MAX_V (100)
#define MAX_V2 (MAX_V * MAX_V)

struct edge {
  ll to;
  ll cap;
  ll rev;
};

vector<edge> G[MAX_V2 * 2 + 10];
bool used[MAX_V2 * 2 + 10];

void append_edge(ll from, ll to, ll cap) {
  G[from].emplace_back(edge{to, cap, (ll)G[to].size()});
  G[to].emplace_back(edge{from, 0, (ll)G[from].size() - 1});
}

int dfs(ll v, ll t, ll f) {
  if (v == t)
    return f;
  used[v] = true;
  for (ll i = 0; i < G[v].size(); i++) {
    auto &e = G[v][i];
    if (!used[e.to] && (0 < e.cap)) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (0 < d) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(ll s, ll t) {
  ll flow = 0;
  for (;;) {
    memset(used, 0, sizeof(used));
    ll f = dfs(s, t, numeric_limits<ll>::max());
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {
  int H, W;
  cin >> H >> W;

  vector<string> S(H);
  ll source = 0;
  ll sink = 0;

  REP(h, H) {
    cin >> S[h];
    REP(w, W) {
      switch (S[h][w]) {
      case 'S':
        source = h * MAX_V + w;
        S[h][w] = 'o';
        break;
      case 'T':
        sink = h * MAX_V + w + MAX_V2;
        S[h][w] = 'o';
        break;
      case 'o':
        break;
      default:
        continue;
      }
      append_edge(h * MAX_V + w + MAX_V2, h * MAX_V + w, 1);
      append_edge(h * MAX_V + w, h * MAX_V + w + MAX_V2, 1);
    }
  }

  REP(h, H) {
    REP(w, W) REP(w2, w) {
      if ((S[h][w] == 'o') && (S[h][w2] == 'o')) {
        append_edge(h * MAX_V + w, h * MAX_V + w2 + MAX_V2, 100001);
        append_edge(h * MAX_V + w2, h * MAX_V + w + MAX_V2, 100001);
      }
    }
  }

  REP(w, W) {
    REP(h, H) REP(h2, h) {
      if ((S[h][w] == 'o') && (S[h2][w] == 'o')) {
        append_edge(h * MAX_V + w, h2 * MAX_V + w + MAX_V2, 100001);
        append_edge(h2 * MAX_V + w, h * MAX_V + w + MAX_V2, 100001);
      }
    }
  }

  int ret = max_flow(source, sink);

  if ((MAX_V2) < ret) {
    ret = -1;
  }

  print(ret);

  return 0;
}