Language: C++

#include <iostream>
#include <sstream>
#include <string>
#include <cassert>
#include <cmath>
#include <climits>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iomanip>

using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

#define REP(i,n) for(int i = 0; i < (int)(n); ++i)
#define FOR(i,a,b) for(int i = (a); i < (int)(b); ++i)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(v) ((int)v.size())

#define pb push_back
#define mp make_pair
#define mt make_tuple

class FordFulkerson {

private:
    // 陦後″蜈医∝ｮｹ驥上・・ｾｺ
    struct edge { int to, cap, rev; };
    const int INF = 1e9;
    vector<vector<edge> > G;
    vector<char> used;

public:

    FordFulkerson(int V){
        G.resize(V);
        used.resize(V);
    }

    void add_uni_edge(int from, int to, int cap) {
        // rev縺ｫ縺ｯ縲・・ｾｺ縺ｮ螳ｹ驥上ｒ縺吶＄縺ｫ蠕励ｋ縺溘ａ縺ｮ繧､繝ｳ繝・ャ繧ｯ繧ｹ繧定ｨ倬鹸
        G[from].push_back( edge{ to, cap, SIZE(G[to])});
        G[to].push_back( edge{from, 0, SIZE(G[from]) - 1});
    }

    // 譛ｪ繝・せ繝・    void add_bi_edge(int v1, int v2, int cap) {
        add_uni_edge(v1, v2, cap);
        add_uni_edge(v2, v1, cap);
    }

    // v縺九ｉt縺ｾ縺ｧ縺ｮ譛螟ｧ豬√ｒ霑斐☆
    // f縺ｯ縲・らせv縺ｮ譎らせ縺ｧ繧上°縺｣縺ｦ縺・ｋ蜿ｯ閭ｽ縺ｪ譛螟ｧ豬√・螟ｧ縺阪＆??
    int dfs(int v, int t, int f) {
        if (v == t) return f;
        used[v] = true;

        // v逡ｪ逶ｮ縺ｮ鬆らせ縺梧戟縺､霎ｺ縺ｧ繝ｫ繝ｼ繝・        REP(i, SIZE(G[v])){
            edge &e = G[v][i];
            // 縺ｾ縺霎ｺe縺ｫ菴呵｣輔′縺ゅｋ蝣ｴ蜷・            if (!used[e.to] && e.cap > 0) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    int max_flow(int s, int t) {
        int flow = 0;
        while (true) {
            fill(ALL(used), 0);
            int f = dfs(s, t, INF);
            if (f == 0) return flow;
            flow += f;
        }
    }

    void debug_print() {
        REP(from, SIZE(G)){
            cout << "from " << from << ": " << endl;
            for (auto e : G[from]) {
                printf(" -> %d, capacity(%d), rev(%d)\n", e.to, e.cap, G[e.to][e.rev].cap);
            }
            cout << endl;
        }
    }

};

int main(void)
{
    cin.sync_with_stdio(false);
    int H, W;
    cin >> H >> W;
    vector<string> cells(H);

    pair<int,int> pos_s;
    pair<int,int> pos_t;
    REP(h, H) {
        cin >> cells[h];
        REP(w, W) {
            if (cells[h][w] == 'S') {
                cells[h][w] = 'o';
                pos_s = mp(h,w);
            }
            else if (cells[h][w] == 'T') {
                cells[h][w] = 'o';
                pos_t = mp(h,w);
            }
        }
    }

    if (pos_s.first == pos_t.first || pos_s.second == pos_t.second) {
        cout << -1 << endl;
        return 0;
    }

    FordFulkerson ff(H + W + 2);
    REP(h, H) {
        REP(w, W) {
            if (cells[h][w] == 'o') {
                ff.add_bi_edge(h, H + w, 1);
            }
        }
    }
    ff.add_uni_edge(H + W, pos_s.first, 1e7);
    ff.add_uni_edge(H + W, H + pos_s.second, 1e7);
    ff.add_uni_edge(pos_t.first, H + W + 1, 1e7);
    ff.add_uni_edge(H + pos_t.second, H + W + 1, 1e7);
    auto flow = ff.max_flow(H + W, H + W + 1);
    cout << flow << endl;

    return 0;
}


Compiler output:
a.cc:55:22: error: 'v1' has not been declared
   55 |         add_uni_edge(v1, v2, cap);
      |                      ^~
a.cc:55:26: error: 'v2' has not been declared
   55 |         add_uni_edge(v1, v2, cap);
      |                          ^~
a.cc:55:30: error: 'cap' has not been declared
   55 |         add_uni_edge(v1, v2, cap);
      |                              ^~~
a.cc:55:9: error: ISO C++ forbids declaration of 'add_uni_edge' with no type [-fpermissive]
   55 |         add_uni_edge(v1, v2, cap);
      |         ^~~~~~~~~~~~
a.cc:55:9: error: 'int FordFulkerson::add_uni_edge(int, int, int)' cannot be overloaded with 'void FordFulkerson::add_uni_edge(int, int, int)'
a.cc:48:10: note: previous declaration 'void FordFulkerson::add_uni_edge(int, int, int)'
   48 |     void add_uni_edge(int from, int to, int cap) {
      |          ^~~~~~~~~~~~
a.cc:56:22: error: 'v2' has not been declared
   56 |         add_uni_edge(v2, v1, cap);
      |                      ^~
a.cc:56:26: error: 'v1' has not been declared
   56 |         add_uni_edge(v2, v1, cap);
      |                          ^~
a.cc:56:30: error: 'cap' has not been declared
   56 |         add_uni_edge(v2, v1, cap);
      |                              ^~~
a.cc:56:9: error: ISO C++ forbids declaration of 'add_uni_edge' with no type [-fpermissive]
   56 |         add_uni_edge(v2, v1, cap);
      |         ^~~~~~~~~~~~
a.cc:56:9: error: 'int FordFulkerson::add_uni_edge(int, int, int)' cannot be overloaded with 'void FordFulkerson::add_uni_edge(int, int, int)'
a.cc:48:10: note: previous declaration 'void FordFulkerson::add_uni_edge(int, int, int)'
   48 |     void add_uni_edge(int from, int to, int cap) {
      |          ^~~~~~~~~~~~
a.cc:57:6: error: expected ';' after class definition
   57 |     }
      |      ^
      |      ;
a.cc: In function 'int dfs(int, int, int)':
a.cc:63:9: error: 'used' was not declared in this scope
   63 |         used[v] = true;
      |         ^~~~
a.cc:66:13: error: 'edge' was not declared in this scope
   66 |             edge &e = G[v][i];
      |             ^~~~
a.cc:66:19: error: 'e' was not declared in this scope
   66 |             edge &e = G[v][i];
      |                   ^
a.cc:66:23: error: 'G' was not declared in this scope
   66 |             edge &e = G[v][i];
      |                       ^
a.cc:66:28: error: 'i' was not declared in this scope
   66 |             edge &e = G[v][i];
      |                            ^
a.cc: At global scope:
a.cc:75:9: error: expected declaration before '}' token
   75 |         }
      |         ^
a.cc:76:9: error: expected unqualified-id before 'return'
   76 |         return 0;
      |         ^~~~~~
a.cc:77:5: error: expected declaration before '}' token
   77 |     }
      |     ^
a.cc: In function 'int max_flow(int, int)':
a.cc:82:22: error: 'used' was not declared in this scope
   82 |             fill(ALL(used), 0);
      |                      ^~~~
a.cc:25:17: note: in definition of macro 'ALL'
   25 | #define ALL(c) (c).begin(), (c).end()
      |                 ^
a.cc:83:31: error: 'INF' was not declared in this scope
   83 |             int f = dfs(s, t, INF);
      |                               ^~~
a.cc: In function 'void debug_print()':
a.cc:90:24: error: 'G' was not declared in this scope
   90 |         REP(from, SIZE(G)){
      |                        ^
a.cc:23:43: note: in definition of macro 'REP'
   23 | #define REP(i,n) for(int i = 0; i < (int)(n); ++i)
      |                                           ^
a.cc:90:19: note: in expansion of macro 'SIZE'
   90 |         REP(from, SIZE(G)){
      |                   ^~~~
a.cc: At global scope:
a.cc:99:1: error: expected declaration before '}' token
   99 | };
      | ^
a.cc: In function 'int main()':
a.cc:133:20: error: 'class FordFulkerson' has no member named 'add_bi_edge'; did you mean 'add_uni_edge'?
  133 |                 ff.add_bi_edge(h, H + w, 1);
      |                    ^~~~~~~~~~~
      |                    add_uni_edge
a.cc:141:20: error: 'class FordFulkerson' has no member named 'max_flow'
  141 |     auto flow = ff.max_flow(H + W, H + W + 1);
      |                    ^~~~~~~~
a.cc: In function 'int dfs(int, int, int)':
a.cc:74:13: warning: control reaches end of non-void function [-Wreturn-type]
   74 |             }
      |             ^