Problem p03718 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <bitset>
#include <chrono>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define RE return 0
// ios::sync_with_stdio(false);
// std::cin.tie(0);
//<< setprecision(20)
const int mod = 1e9 + 7;
const int big = 1e9 + 100;
const long double pai = 3.141592653589793238462643383279502884197;
const long double ena = 2.71828182845904523536;
const long double eps = 1e-7;
template <class T, class U> void mineq(T &a, U b) {
  if (a > b) {
    a = b;
  }
}
template <class T, class U> void maxeq(T &a, U b) {
  if (a < b) {
    a = b;
  }
}
template <class T> void soun(T &ar) {
  sort(ar.begin(), ar.end());
  ar.erase(unique(ar.begin(), ar.end()), ar.end());
}
class dinic {
public:
  int n, sta, gol;
  vector<vector<llint>> hen;
  vector<int> dis; // bfsの距離
  // 隣接行列(O(VVE)なので)
  dinic(int in, int s, int g) {
    n = in;
    sta = s;
    gol = g;
    hen.res(in);
    dis.res(in);
    for (int i = 0; i < n; i++) {
      hen[i].res(in);
    }
  }
  void add(int u, int v, llint wei) { hen[u][v] += wei; }
  // 隣接なので逆編情報が不要!!
  // 増加のbfsする
  // それが増加する向きだけに流す
  // 流れないなら、終了!
  void bfs(void) {
    int i;
    for (i = 0; i < n; i++) {
      dis[i] = -1;
    } // 初期化
    queue<pair<int, int>> que;
    que.push(mp(0, sta));
    dis[sta] = 0;
    while (!que.empty()) {

      int kyo = que.front().fir;
      int town = que.front().sec;
      que.pop();
      for (i = 0; i < n; i++) {
        if (hen[town][i] != 0 && dis[i] == -1) {
          dis[i] = kyo + 1;
          que.push(mp(kyo + 1, i));
        }
      }
    }
  }
  llint dfs(int ter, llint lim) {
    // それまでの上限がlim
    // 流した量を返す
    if (ter == gol) {
      return lim;
    }
    llint ans = 0;
    int i;
    for (i = 0; i < n; i++) {
      if (dis[ter] >= dis[i] || hen[ter][i] == 0) {
        continue;
      } // dinic
      if (lim == ans) {
        break;
      }
      llint nga = dfs(i, min(lim - ans, hen[ter][i]));
      ans += nga;
      hen[ter][i] -= nga;
      hen[i][ter] += nga;
    }
    return ans;
  }
  llint solve(void) {
    llint ans = 0;
    while (-1) {
      bfs();
      llint nga = dfs(sta, big);
      ans += nga;
      if (nga == 0) {
        break;
      }
    }
    return ans;
  }
};
int main(void) {
  int h, w, i, j;
  cin >> h >> w;
  dinic gra(h + w, -1, -1); // ダミー
  vector<string> mat(h);
  for (i = 0; i < h; i++) {
    cin >> mat[i];
    for (j = 0; j < w; j++) {
      if (mat[i][j] == 'o') {
        gra.add(h + j, i, 1);
        gra.add(i, h + j, 1);
      }
      if (mat[i][j] == 'S') {
        gra.sta = i;
        gra.add(h + j, i, 999999);
        gra.add(i, h + j, 999999);
      }
      if (mat[i][j] == 'T') {
        gra.gol = i;
        gra.add(h + j, i, 999999);
        gra.add(i, h + j, 999999);
      }
    }
  }
  int ans = gra.solve();
  if (ans < 999876) {
    cout << ans << endl;
  } else {
    cout << -1 << endl;
  }
  RE;
}

Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <chrono>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define RE return 0
// ios::sync_with_stdio(false);
// std::cin.tie(0);
//<< setprecision(20)
const int mod = 1e9 + 7;
const int big = 1e9 + 100;
const long double pai = 3.141592653589793238462643383279502884197;
const long double ena = 2.71828182845904523536;
const long double eps = 1e-7;
template <class T, class U> void mineq(T &a, U b) {
  if (a > b) {
    a = b;
  }
}
template <class T, class U> void maxeq(T &a, U b) {
  if (a < b) {
    a = b;
  }
}
template <class T> void soun(T &ar) {
  sort(ar.begin(), ar.end());
  ar.erase(unique(ar.begin(), ar.end()), ar.end());
}
class dinic {
public:
  int n, sta, gol;
  vector<vector<llint>> hen;
  vector<int> dis; // bfsの距離
  // 隣接行列(O(VVE)なので)
  dinic(int in, int s, int g) {
    n = in;
    sta = s;
    gol = g;
    hen.res(in);
    dis.res(in);
    for (int i = 0; i < n; i++) {
      hen[i].res(in);
    }
  }
  void add(int u, int v, llint wei) { hen[u][v] += wei; }
  // 隣接なので逆編情報が不要!!
  // 増加のbfsする
  // それが増加する向きだけに流す
  // 流れないなら、終了!
  void bfs(void) {
    int i;
    for (i = 0; i < n; i++) {
      dis[i] = -1;
    } // 初期化
    queue<pair<int, int>> que;
    que.push(mp(0, sta));
    dis[sta] = 0;
    while (!que.empty()) {

      int kyo = que.front().fir;
      int town = que.front().sec;
      que.pop();
      for (i = 0; i < n; i++) {
        if (hen[town][i] != 0 && dis[i] == -1) {
          dis[i] = kyo + 1;
          que.push(mp(kyo + 1, i));
        }
      }
    }
  }
  llint dfs(int ter, llint lim) {
    // それまでの上限がlim
    // 流した量を返す
    if (ter == gol) {
      return lim;
    }
    llint ans = 0;
    int i;
    for (i = 0; i < n; i++) {
      if (dis[ter] >= dis[i] || hen[ter][i] == 0) {
        continue;
      } // dinic
      if (lim == ans) {
        break;
      }
      llint nga = dfs(i, min(lim - ans, hen[ter][i]));
      ans += nga;
      hen[ter][i] -= nga;
      hen[i][ter] += nga;
    }
    return ans;
  }
  llint solve(void) {
    llint ans = 0;
    while (-1) {
      bfs();
      llint nga = dfs(sta, big);
      ans += nga;
      if (nga == 0) {
        break;
      }
    }
    return ans;
  }
};
int main(void) {
  int h, w, i, j;
  cin >> h >> w;
  dinic gra(h + w, -1, -1); // ダミー
  vector<string> mat(h);
  for (i = 0; i < h; i++) {
    cin >> mat[i];
    for (j = 0; j < w; j++) {
      if (mat[i][j] == 'o') {
        gra.add(h + j, i, 1);
        gra.add(i, h + j, 1);
      }
      if (mat[i][j] == 'S') {
        gra.sta = i;
        gra.add(h + j, i, 999999);
        gra.add(i, h + j, 999999);
      }
      if (mat[i][j] == 'T') {
        gra.gol = i;
        gra.add(h + j, i, 999999);
        gra.add(i, h + j, 999999);
      }
    }
  }
  if (gra.sta == gra.gol) {
    cout << -1 << endl;
    RE;
  }
  int ans = gra.solve();
  if (ans < 999876) {
    cout << ans << endl;
  } else {
    cout << -1 << endl;
  }
  RE;
}