Problem p03718 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
// #define int         int64_t
#define ii pair<int, int>
#define dd pair<double, double>
#define vi vector<int>
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define checkBit(v, p) (v & (1LL << p))
#define loop(i, a, b) for (int i = a; i < int(b); i++)
#define x first
#define y second
using namespace std;
int inf = 2e9, mod = 1e9 + 7;

struct edge {
  int u, v;
  int cap, flow;
  edge() {}
  edge(int u, int v, int cap) : u(u), v(v), cap(cap), flow(0) {}
};

struct Dinic {
  int N;
  vector<edge> E;
  vector<vector<int>> g;
  vector<int> d, pt;

  Dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}

  void Addedge(int u, int v, int cap) {
    if (u != v) {
      E.emplace_back(edge(u, v, cap));
      g[u].emplace_back(E.size() - 1);
      E.emplace_back(edge(u, v, 0));
      g[v].emplace_back(E.size() - 1);
    }
  }

  bool BFS(int S, int T) {
    queue<int> q({S});
    fill(d.begin(), d.end(), N + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T)
        break;
      for (int k : g[u]) {
        edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.emplace(e.v);
        }
      }
    }
    return d[T] != N + 1;
  }

  int DFS(int u, int T, int flow = -1) {
    if (u == T || flow == 0)
      return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      edge &e = E[g[u][i]];
      edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        int amt = e.cap - e.flow;
        if (flow != -1 && amt > flow)
          amt = flow;
        if (int pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }

  int MaxFlow(int S, int T) {
    int total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (int flow = DFS(S, T))
        total += flow;
    }
    return total;
  }
};

int32_t main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int n, m;
  cin >> n >> m;
  char c;
  Dinic din(n + m + 2);
  ii p = {-1, -1};
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c;
      if (c == '.')
        continue;
      din.Addedge(i, n + j, 1);
      din.Addedge(n + j, i, 1);
      if (c == 'S') {
        din.Addedge(n + m, i, 1e6), din.Addedge(n + m, n + j, 1e6);
        if (p.x != i && p.y != j)
          p = {i, j};
        else
          return cout << -1 << endl, 0;
      }
      if (c == 'T') {
        din.Addedge(i, n + m + 1, 1e6), din.Addedge(n + j, n + m + 1, 1e6);
        if (p.x != i && p.y != j)
          p = {i, j};
        else
          return cout << -1 << endl, 0;
      }
    }
  }
  cout << din.MaxFlow(n + m, n + m + 1) << endl;
  ;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
// #define int         int64_t
#define ii pair<int, int>
#define dd pair<double, double>
#define vi vector<int>
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define checkBit(v, p) (v & (1LL << p))
#define loop(i, a, b) for (int i = a; i < int(b); i++)
#define x first
#define y second
using namespace std;
int inf = 2e9, mod = 1e9 + 7;

struct edge {
  int u, v;
  int cap, flow;
  edge() {}
  edge(int u, int v, int cap) : u(u), v(v), cap(cap), flow(0) {}
};

struct Dinic {
  int N;
  vector<edge> E;
  vector<vector<int>> g;
  vector<int> d, pt;

  Dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}

  void Addedge(int u, int v, int cap) {
    if (u != v) {
      E.emplace_back(edge(u, v, cap));
      g[u].emplace_back(E.size() - 1);
      E.emplace_back(edge(v, u, 0));
      g[v].emplace_back(E.size() - 1);
    }
  }

  bool BFS(int S, int T) {
    queue<int> q({S});
    fill(d.begin(), d.end(), N + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T)
        break;
      for (int k : g[u]) {
        edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.emplace(e.v);
        }
      }
    }
    return d[T] != N + 1;
  }

  int DFS(int u, int T, int flow = -1) {
    if (u == T || flow == 0)
      return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      edge &e = E[g[u][i]];
      edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        int amt = e.cap - e.flow;
        if (flow != -1 && amt > flow)
          amt = flow;
        if (int pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }

  int MaxFlow(int S, int T) {
    int total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (int flow = DFS(S, T))
        total += flow;
    }
    return total;
  }
};

int32_t main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int n, m;
  cin >> n >> m;
  char c;
  Dinic din(n + m + 2);
  ii p = {-1, -1};
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c;
      if (c == '.')
        continue;
      din.Addedge(i, n + j, 1);
      din.Addedge(n + j, i, 1);
      if (c == 'S') {
        din.Addedge(n + m, i, 1e6), din.Addedge(n + m, n + j, 1e6);
        if (p.x != i && p.y != j)
          p = {i, j};
        else
          return cout << -1 << endl, 0;
      }
      if (c == 'T') {
        din.Addedge(i, n + m + 1, 1e6), din.Addedge(n + j, n + m + 1, 1e6);
        if (p.x != i && p.y != j)
          p = {i, j};
        else
          return cout << -1 << endl, 0;
      }
    }
  }
  cout << din.MaxFlow(n + m, n + m + 1) << endl;
  ;
  return 0;
}