Problem p03718 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;

#define sz size()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(c) (c).begin(), (c).end()
#define rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define per(i, a, b) for (ll i = b - 1LL; i >= (a); --i)
#define clr(a, b) memset((a), (b), sizeof(a))
#define ctos(c) string(1, c)
#define print(x) cout << #x << " = " << x << endl;

#define MOD 1000000007

#define MAX_V 220
#define INF 1000000000000000000LL

struct edge {
  long long to, reve;
  long long cap;
};

vector<edge> E[MAX_V];
long long itr[MAX_V], lev[MAX_V];

void ae(long long x, long long y, long long cap) {
  E[x].push_back((edge){y, (int)E[y].size(), cap});
  E[y].push_back((edge){x, (int)E[x].size() - 1, 0});
}

void bfs(long long cur) {
  memset(lev, -1, sizeof(lev));
  queue<long long> q;
  lev[cur] = 0;
  q.push(cur);
  while (q.size()) {
    long long v = q.front();
    q.pop();
    for (long long i = 0; i < E[v].size(); i++) {
      edge &e = E[v][i];
      if (e.cap > 0 && lev[e.to] < 0) {
        lev[e.to] = lev[v] + 1, q.push(e.to);
      }
    }
  }
}

long long dfs(long long from, long long to, long long cf) {
  if (from == to)
    return cf;
  for (long long &i = itr[from]; i < E[from].size(); i++) {
    edge &e = E[from][i];
    if (e.cap > 0 && lev[from] < lev[e.to]) {
      long long f = dfs(e.to, to, min(cf, e.cap));
      if (f > 0) {
        e.cap -= f;
        E[e.to][e.reve].cap += f;
        return f;
      }
    }
  }
  return 0;
}

long long maxFlowDinic(long long from, long long to) {
  long long fl = 0, tf;
  while (1) {
    bfs(from);
    if (lev[to] < 0)
      return fl;
    memset(itr, 0, sizeof(itr));
    while ((tf = dfs(from, to, numeric_limits<int>::max())) > 0)
      fl += tf;
  }
}

int main() {
  ll h, w;
  cin >> h >> w;
  vector<string> vs;
  rep(i, 0, h) {
    string s;
    cin >> s;
    vs.pb(s);
  }
  ll sy, sx;
  ll gy, gx;
  rep(y, 0, h) {
    rep(x, 0, w) {
      if (vs[y][x] == 'o') {
        ae(y, h + x, 1);
        ae(h + x, y, 1);
      }
      if (vs[y][x] == 'S') {
        sy = y;
        sx = x;
      }
      if (vs[y][x] == 'T') {
        gy = y;
        gx = x;
      }
    }
  }
  if (sy == gy || sx == gx) {
    cout << -1 << endl;
    return 0;
  }
  ll start = h * w + 1;
  ll goal = h * w + 2;
  rep(i, 0, h) {
    ae(start, sy, 1000);
    ae(start, h + sx, 1000);
    ae(gy, goal, 1000);
    ae(h + gx, goal, 1000);
  }
  cout << maxFlowDinic(start, goal) << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;

#define sz size()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(c) (c).begin(), (c).end()
#define rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define per(i, a, b) for (ll i = b - 1LL; i >= (a); --i)
#define clr(a, b) memset((a), (b), sizeof(a))
#define ctos(c) string(1, c)
#define print(x) cout << #x << " = " << x << endl;

#define MOD 1000000007

#define MAX_V 220
#define INF 1000000000000000000LL

struct edge {
  long long to, reve;
  long long cap;
};

vector<edge> E[MAX_V];
long long itr[MAX_V], lev[MAX_V];

void ae(long long x, long long y, long long cap) {
  E[x].push_back((edge){y, (int)E[y].size(), cap});
  E[y].push_back((edge){x, (int)E[x].size() - 1, 0});
}

void bfs(long long cur) {
  memset(lev, -1, sizeof(lev));
  queue<long long> q;
  lev[cur] = 0;
  q.push(cur);
  while (q.size()) {
    long long v = q.front();
    q.pop();
    for (long long i = 0; i < E[v].size(); i++) {
      edge &e = E[v][i];
      if (e.cap > 0 && lev[e.to] < 0) {
        lev[e.to] = lev[v] + 1, q.push(e.to);
      }
    }
  }
}

long long dfs(long long from, long long to, long long cf) {
  if (from == to)
    return cf;
  for (long long &i = itr[from]; i < E[from].size(); i++) {
    edge &e = E[from][i];
    if (e.cap > 0 && lev[from] < lev[e.to]) {
      long long f = dfs(e.to, to, min(cf, e.cap));
      if (f > 0) {
        e.cap -= f;
        E[e.to][e.reve].cap += f;
        return f;
      }
    }
  }
  return 0;
}

long long maxFlowDinic(long long from, long long to) {
  long long fl = 0, tf;
  while (1) {
    bfs(from);
    if (lev[to] < 0)
      return fl;
    memset(itr, 0, sizeof(itr));
    while ((tf = dfs(from, to, numeric_limits<int>::max())) > 0)
      fl += tf;
  }
}

int main() {
  ll h, w;
  cin >> h >> w;
  vector<string> vs;
  rep(i, 0, h) {
    string s;
    cin >> s;
    vs.pb(s);
  }
  ll sy, sx;
  ll gy, gx;
  rep(y, 0, h) {
    rep(x, 0, w) {
      if (vs[y][x] == 'o') {
        ae(y, h + x, 1);
        ae(h + x, y, 1);
      }
      if (vs[y][x] == 'S') {
        sy = y;
        sx = x;
      }
      if (vs[y][x] == 'T') {
        gy = y;
        gx = x;
      }
    }
  }
  if (sy == gy || sx == gx) {
    cout << -1 << endl;
    return 0;
  }
  ll start = h + w + 1;
  ll goal = h + w + 2;
  rep(i, 0, h) {
    ae(start, sy, 1000);
    ae(start, h + sx, 1000);
    ae(gy, goal, 1000);
    ae(h + gx, goal, 1000);
  }
  cout << maxFlowDinic(start, goal) << endl;
  return 0;
}