Problem p03718 (C++)

Buggy submission (status: Runtime Error):

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
// #include <regex>

/* g++ -g -std=c++0x */
/* g++ -g -std=c++11 */

using namespace std;

// std::ios::sync_with_stdio(false);

// freopen("input.txt", "rt", stdin);
// freopen("output.txt", "wt", stdout);

#define ALL(c) (c).begin(), (c).end()
#define ALLR(c) (c).rbegin(), (c).rend()
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORR(i, a, b) for (int i = (a); i > (b); --i)
#define FOR_ALL(i, c)                                                          \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define FOR_ALLR(i, c)                                                         \
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); ++i)
#define SZ(array) (sizeof(array) / sizeof(array[0]))
#define lc(x) (x << 1)       /* 2*x */
#define rc(x) (x << 1 | 1)   /* 2*x+1 */
#define lowbit(x) (x & (-x)) /* 0b10100 -> 0b100 */

typedef long long LL;
typedef map<int, int> MII;
typedef pair<int, int> PII;
typedef set<int> SI;
typedef vector<bool> VB;
typedef vector<double> VD;
typedef vector<int> VI;
typedef vector<string> VS;

/* check if a key is in container C */
template <class C> inline bool in_(const typename C::key_type &k, const C &A) {
  return A.find(k) != A.end();
}
inline bool in_(const string &s, const string &S) {
  return S.find(s) != string::npos;
}

const int inf = 1e9;

struct Network {
  static const int maxv = 1e5;
  static const int maxe = 1e6;
  struct Edge {
    int u, v, cap, next, tag;
  } E[maxe];
  int ne, head[maxv], head_[maxv], dis[maxv], Q[maxv], du[maxv];

  void init() {
    ne = 0;
    memset(head, -1, sizeof(head));
    memset(du, 0, sizeof(du));
  }

  void addedge(const int u, const int v, const int c, const int tag = 0) {
    assert(0 <= u && u < maxv && 0 <= v && v < maxv);
    assert(ne < maxe - 1);
    E[ne].u = u;
    E[ne].v = v;
    E[ne].cap = c;
    E[ne].tag = tag;
    E[ne].next = head[u];
    head[u] = ne++;
    E[ne].u = v;
    E[ne].v = u;
    E[ne].cap = 0;
    E[ne].tag = 0;
    E[ne].next = head[v];
    head[v] = ne++;
  }

  bool bfs(const int src, const int sink) {
    memset(dis, -1, sizeof(dis));
    int front, end;
    front = 0;
    end = 1;
    Q[front] = src;
    dis[src] = 0;
    while (front != end) {
      const int u = Q[front++];
      for (int i = head[u]; i != -1; i = E[i].next) {
        const int v = E[i].v;
        if (E[i].cap && dis[v] == -1) {
          dis[v] = dis[u] + 1;
          Q[end++] = v;
        }
      }
    }
    return dis[sink] != -1;
  }

  int dfs(const int u, const int sink, const int flow) {
    if (u == sink)
      return flow;
    for (int &i = head_[u]; i != -1; i = E[i].next) {
      const int v = E[i].v;
      const int minf = min(E[i].cap, flow);
      int f;
      if (E[i].cap && dis[v] == dis[u] + 1 && (f = dfs(v, sink, minf))) {
        E[i].cap -= f;
        E[i ^ 1].cap += f;
        return f;
      }
    }
    return 0;
  }

  int dinic(const int src, const int sink) {
    int flow = 0;
    while (bfs(src, sink)) {
      memcpy(head_, head, sizeof(head));
      int f;
      while (f = dfs(src, sink, inf)) {
        flow += f;
        flow = min(flow, inf);
      }
    }
    return flow;
  }

  int maxflow(const int src, const int sink) { return dinic(src, sink); }
} G;

const int maxn = 110;
char A[maxn][maxn];
int H, W;

int ij2v(const int i, const int j) { return i * W + j; }

int main() {
  /* #ifndef ONLINE_JUDGE */
  /*     freopen("foo", "rt", stdin); */
  /* #endif */
  while (cin >> H >> W) {
    G.init();
    set<char> leaf = {'S', 'T', 'o'};
    const int N = H * W;
    int src, tgt;
    FOR(i, 0, H) FOR(j, 0, W) {
      cin >> A[i][j];
      if (A[i][j] == 'S')
        src = ij2v(i, j);
      if (A[i][j] == 'T')
        tgt = ij2v(i, j);
    }
    FOR(i, 0, H) FOR(j, 0, W) if (in_(A[i][j], leaf)) {
      const int u = ij2v(i, j);
      const int v = u + N;
      const int c = A[i][j] == 'o' ? 1 : inf;
      G.addedge(u, v, c);
      FOR(k, i + 1, H) if (in_(A[k][j], leaf)) {
        const int x = ij2v(k, j);
        const int y = x + N;
        G.addedge(v, x, inf);
        G.addedge(y, u, inf);
      }
      FOR(k, j + 1, W) if (in_(A[i][k], leaf)) {
        const int x = ij2v(i, k);
        const int y = x + N;
        G.addedge(v, x, inf);
        G.addedge(y, u, inf);
      }
    }
    const int f = G.maxflow(src, tgt);
    const int ans = f < inf ? f : -1;
    cout << ans << endl;
  }
  return 0;
}


Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
// #include <regex>

/* g++ -g -std=c++0x */
/* g++ -g -std=c++11 */

using namespace std;

// std::ios::sync_with_stdio(false);

// freopen("input.txt", "rt", stdin);
// freopen("output.txt", "wt", stdout);

#define ALL(c) (c).begin(), (c).end()
#define ALLR(c) (c).rbegin(), (c).rend()
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORR(i, a, b) for (int i = (a); i > (b); --i)
#define FOR_ALL(i, c)                                                          \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define FOR_ALLR(i, c)                                                         \
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); ++i)
#define SZ(array) (sizeof(array) / sizeof(array[0]))
#define lc(x) (x << 1)       /* 2*x */
#define rc(x) (x << 1 | 1)   /* 2*x+1 */
#define lowbit(x) (x & (-x)) /* 0b10100 -> 0b100 */

typedef long long LL;
typedef map<int, int> MII;
typedef pair<int, int> PII;
typedef set<int> SI;
typedef vector<bool> VB;
typedef vector<double> VD;
typedef vector<int> VI;
typedef vector<string> VS;

/* check if a key is in container C */
template <class C> inline bool in_(const typename C::key_type &k, const C &A) {
  return A.find(k) != A.end();
}
inline bool in_(const string &s, const string &S) {
  return S.find(s) != string::npos;
}

const int inf = 1e9;

struct Network {
  static const int maxv = 1e5;
  static const int maxe = 5e6;
  struct Edge {
    int u, v, cap, next, tag;
  } E[maxe];
  int ne, head[maxv], head_[maxv], dis[maxv], Q[maxv], du[maxv];

  void init() {
    ne = 0;
    memset(head, -1, sizeof(head));
    memset(du, 0, sizeof(du));
  }

  void addedge(const int u, const int v, const int c, const int tag = 0) {
    assert(0 <= u && u < maxv && 0 <= v && v < maxv);
    assert(ne < maxe - 1);
    E[ne].u = u;
    E[ne].v = v;
    E[ne].cap = c;
    E[ne].tag = tag;
    E[ne].next = head[u];
    head[u] = ne++;
    E[ne].u = v;
    E[ne].v = u;
    E[ne].cap = 0;
    E[ne].tag = 0;
    E[ne].next = head[v];
    head[v] = ne++;
  }

  bool bfs(const int src, const int sink) {
    memset(dis, -1, sizeof(dis));
    int front, end;
    front = 0;
    end = 1;
    Q[front] = src;
    dis[src] = 0;
    while (front != end) {
      const int u = Q[front++];
      for (int i = head[u]; i != -1; i = E[i].next) {
        const int v = E[i].v;
        if (E[i].cap && dis[v] == -1) {
          dis[v] = dis[u] + 1;
          Q[end++] = v;
        }
      }
    }
    return dis[sink] != -1;
  }

  int dfs(const int u, const int sink, const int flow) {
    if (u == sink)
      return flow;
    for (int &i = head_[u]; i != -1; i = E[i].next) {
      const int v = E[i].v;
      const int minf = min(E[i].cap, flow);
      int f;
      if (E[i].cap && dis[v] == dis[u] + 1 && (f = dfs(v, sink, minf))) {
        E[i].cap -= f;
        E[i ^ 1].cap += f;
        return f;
      }
    }
    return 0;
  }

  int dinic(const int src, const int sink) {
    int flow = 0;
    while (bfs(src, sink)) {
      memcpy(head_, head, sizeof(head));
      int f;
      while (f = dfs(src, sink, inf)) {
        flow += f;
        flow = min(flow, inf);
      }
    }
    return flow;
  }

  int maxflow(const int src, const int sink) { return dinic(src, sink); }
} G;

const int maxn = 110;
char A[maxn][maxn];
int H, W;

int ij2v(const int i, const int j) { return i * W + j; }

int main() {
  /* #ifndef ONLINE_JUDGE */
  /*     freopen("foo", "rt", stdin); */
  /* #endif */
  while (cin >> H >> W) {
    G.init();
    set<char> leaf = {'S', 'T', 'o'};
    const int N = H * W;
    int src, tgt;
    FOR(i, 0, H) FOR(j, 0, W) {
      cin >> A[i][j];
      if (A[i][j] == 'S')
        src = ij2v(i, j);
      if (A[i][j] == 'T')
        tgt = ij2v(i, j);
    }
    FOR(i, 0, H) FOR(j, 0, W) if (in_(A[i][j], leaf)) {
      const int u = ij2v(i, j);
      const int v = u + N;
      const int c = A[i][j] == 'o' ? 1 : inf;
      G.addedge(u, v, c);
      FOR(k, i + 1, H) if (in_(A[k][j], leaf)) {
        const int x = ij2v(k, j);
        const int y = x + N;
        G.addedge(v, x, inf);
        G.addedge(y, u, inf);
      }
      FOR(k, j + 1, W) if (in_(A[i][k], leaf)) {
        const int x = ij2v(i, k);
        const int y = x + N;
        G.addedge(v, x, inf);
        G.addedge(y, u, inf);
      }
    }
    const int f = G.maxflow(src, tgt);
    const int ans = f < inf ? f : -1;
    cout << ans << endl;
  }
  return 0;
}