Problem p03718 (C++)

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

typedef long long ll;
typedef double lf;
typedef long double Lf;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define TRACE(x) cerr << #x << "  " << x << endl
#define FOR(i, a, b) for (int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define _ << " " <<

#define fi first
#define sec second
#define mp make_pair
#define pb push_back

namespace Dinic {
const int MAXV = 300;
const int MAXE = 105 * 105;
const int oo = 1e6;

int V, E;
int last[MAXV], dist[MAXV], curr[MAXV];
int next[MAXE], adj[MAXE];
int cap[MAXE];

void init(int n) {
  V = n;
  E = 0;
  REP(i, V) last[i] = -1;
}

void edge(int x, int y, int c1, int c2) {
  adj[E] = y;
  cap[E] = c1;
  next[E] = last[x];
  last[x] = E++;
  adj[E] = x;
  cap[E] = c2;
  next[E] = last[y];
  last[y] = E++;
}

int push(int x, int sink, int flow) {
  if (x == sink)
    return flow;

  for (int &e = curr[x]; e != -1; e = next[e]) {
    int y = adj[e];

    if (cap[e] && dist[x] + 1 == dist[y])
      if (int f = push(y, sink, min(flow, cap[e])))
        return cap[e] -= f, cap[e ^ 1] += f, f;
  }
  return 0;
}

int run(int src, int sink) {
  int ret = 0;
  for (;;) {
    REP(i, V) curr[i] = last[i];
    REP(i, V) dist[i] = -1;

    queue<int> Q;
    Q.push(src), dist[src] = 0;

    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();

      for (int e = last[x]; e != -1; e = next[e]) {
        int y = adj[e];
        if (cap[e] && dist[y] == -1)
          Q.push(y), dist[y] = dist[x] + 1;
      }
    }
    if (dist[sink] == -1)
      break;

    while (int f = push(src, sink, oo))
      ret += f;
  }
  return ret;
}
} // namespace Dinic

const int MAXN = 105;

int n, m;
char s[MAXN][MAXN];

int main() {
  scanf("%d %d", &n, &m);
  REP(i, n) scanf("%s", s[i]);

  pii S, T;
  REP(i, n) {
    REP(j, m) {
      if (s[i][j] == 'S')
        S = {i, j};
      if (s[i][j] == 'T')
        T = {i, j};
    }
  }

  if (S.fi == T.fi || S.sec == T.sec) {
    puts("-1");
    return 0;
  }

  Dinic::init(n + m + 2);
  REP(i, n) {
    REP(j, m) {
      if (s[i][j] == 'o') {
        Dinic::edge(i, j + n, 1, 1);
      }
    }
  }
  Dinic::edge(n + m, S.fi, 10000, 10000);
  Dinic::edge(n + m, S.sec + n, 10000, 10000);
  Dinic::edge(T.fi, n + m + 1, 10000, 10000);
  Dinic::edge(T.sec + n, n + m + 1, 10000, 10000);
  printf("%d\n", Dinic::run(n + m, n + m + 1));
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef double lf;
typedef long double Lf;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define TRACE(x) cerr << #x << "  " << x << endl
#define FOR(i, a, b) for (int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define _ << " " <<

#define fi first
#define sec second
#define mp make_pair
#define pb push_back

namespace Dinic {
const int MAXV = 300;
const int MAXE = MAXV * MAXV;
const int oo = 1e8;

int V, E;
int last[MAXV], dist[MAXV], curr[MAXV];
int next[MAXE], adj[MAXE];
int cap[MAXE];

void init(int n) {
  V = n;
  E = 0;
  REP(i, V) last[i] = -1;
}

void edge(int x, int y, int c1, int c2) {
  adj[E] = y;
  cap[E] = c1;
  next[E] = last[x];
  last[x] = E++;
  adj[E] = x;
  cap[E] = c2;
  next[E] = last[y];
  last[y] = E++;
}

int push(int x, int sink, int flow) {
  if (x == sink)
    return flow;

  for (int &e = curr[x]; e != -1; e = next[e]) {
    int y = adj[e];

    if (cap[e] && dist[x] + 1 == dist[y])
      if (int f = push(y, sink, min(flow, cap[e])))
        return cap[e] -= f, cap[e ^ 1] += f, f;
  }
  return 0;
}

int run(int src, int sink) {
  int ret = 0;
  for (;;) {
    REP(i, V) curr[i] = last[i];
    REP(i, V) dist[i] = -1;

    queue<int> Q;
    Q.push(src), dist[src] = 0;

    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();

      for (int e = last[x]; e != -1; e = next[e]) {
        int y = adj[e];
        if (cap[e] && dist[y] == -1)
          Q.push(y), dist[y] = dist[x] + 1;
      }
    }
    if (dist[sink] == -1)
      break;

    while (int f = push(src, sink, oo))
      ret += f;
  }
  return ret;
}
} // namespace Dinic

const int MAXN = 105;

int n, m;
char s[MAXN][MAXN];

int main() {
  scanf("%d %d", &n, &m);
  REP(i, n) scanf("%s", s[i]);

  pii S, T;
  REP(i, n) {
    REP(j, m) {
      if (s[i][j] == 'S')
        S = {i, j};
      if (s[i][j] == 'T')
        T = {i, j};
    }
  }

  if (S.fi == T.fi || S.sec == T.sec) {
    puts("-1");
    return 0;
  }

  Dinic::init(n + m + 2);
  REP(i, n) {
    REP(j, m) {
      if (s[i][j] == 'o') {
        Dinic::edge(i, j + n, 1, 1);
      }
    }
  }
  Dinic::edge(n + m, S.fi, 10000, 10000);
  Dinic::edge(n + m, S.sec + n, 10000, 10000);
  Dinic::edge(T.fi, n + m + 1, 10000, 10000);
  Dinic::edge(T.sec + n, n + m + 1, 10000, 10000);
  printf("%d\n", Dinic::run(n + m, n + m + 1));
  return 0;
}