Problem p03718 (C++)

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

const int N = 233;
const int INF = 1 << 28;

struct edge {
  int to, cap, next;
  edge(int t = 0, int c = 0, int n = 0) : to(t), next(n), cap(c) {}
};
edge G[N * N * 10];
int head[N * N], cur[N * N];
int Gcnt, n, m, S, T, clc, cnt, ans;
char mp[N][N];
int dis[N * N], vis[N * N];
int in[N][N], out[N][N];
int r[N], c[N];
queue<int> Q;

inline void AddEdge(int from, int to, int cap) {
  G[++Gcnt] = edge(to, cap, head[from]);
  head[from] = Gcnt;
  G[++Gcnt] = edge(from, 0, head[to]);
  head[to] = Gcnt;
}
inline bool bfs(int S, int T) {
  dis[S] = 0;
  Q.push(S);
  vis[S] = ++clc;
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    for (int i = head[u]; i; i = G[i].next) {
      edge &e = G[i];
      if (e.cap && vis[e.to] != clc) {
        dis[e.to] = dis[u] + 1;
        vis[e.to] = clc;
        Q.push(e.to);
      }
    }
  }
  return vis[T] == clc;
}
inline int dfs(int u, int a) {
  int flow = 0, f;
  if (u == T || a == 0)
    return a;
  for (int &i = cur[u]; i; i = G[i].next) {
    edge &e = G[i];
    if (e.cap && dis[e.to] == dis[u] + 1 &&
        (f = dfs(e.to, min(a, e.cap))) > 0) {
      e.cap -= f;
      flow += f;
      G[i ^ 1].cap -= f;
      a -= f;
      if (a == 0)
        break;
    }
  }
  return flow;
}
inline int MaxFlow(int S, int T) {
  int flow = 0;
  while (bfs(S, T)) {
    for (int i = 1; i <= cnt; i++)
      cur[i] = head[i];
    flow += dfs(S, INF);
  }
  return flow;
}

int main(void) {
  Gcnt = 1;
  scanf("%d %d\n", &n, &m);
  S = ++cnt;
  T = ++cnt;
  for (int i = 1; i <= n; i++) {
    scanf("%s", mp[i] + 1);
    for (int j = 1; j <= m; j++)
      if (mp[i][j] == 'o') {
        in[i][j] = ++cnt;
        out[i][j] = ++cnt;
      }
  }
  for (int i = 1; i <= n; i++)
    r[i] = ++cnt;
  for (int i = 1; i <= m; i++)
    c[i] = ++cnt;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (mp[i][j] == 'S') {
        AddEdge(S, r[i], INF);
        AddEdge(S, c[j], INF);
      } else if (mp[i][j] == 'T') {
        AddEdge(r[i], T, INF);
        AddEdge(c[j], T, INF);
      } else if (mp[i][j] == 'o') {
        AddEdge(r[i], in[i][j], INF);
        AddEdge(c[j], in[i][j], INF);
        AddEdge(in[i][j], out[i][j], 1);
        AddEdge(out[i][j], r[i], INF);
        AddEdge(out[i][j], c[j], INF);
      }
  ans = MaxFlow(S, T);
  if (ans > n * m)
    ans = -1;
  cout << ans << endl;
  return 0;
}


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

const int N = 233;
const int INF = 1 << 28;

struct edge {
  int to, cap, next;
  edge(int t = 0, int c = 0, int n = 0) : to(t), next(n), cap(c) {}
};
edge G[N * N * 10];
int head[N * N], cur[N * N];
int Gcnt, n, m, S, T, clc, cnt, ans;
char mp[N][N];
int dis[N * N], vis[N * N];
int in[N][N], out[N][N];
int r[N], c[N];
queue<int> Q;

inline void AddEdge(int from, int to, int cap) {
  G[++Gcnt] = edge(to, cap, head[from]);
  head[from] = Gcnt;
  G[++Gcnt] = edge(from, 0, head[to]);
  head[to] = Gcnt;
}
inline bool bfs(int S, int T) {
  dis[S] = 0;
  Q.push(S);
  vis[S] = ++clc;
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    for (int i = head[u]; i; i = G[i].next) {
      edge &e = G[i];
      if (e.cap && vis[e.to] != clc) {
        dis[e.to] = dis[u] + 1;
        vis[e.to] = clc;
        Q.push(e.to);
      }
    }
  }
  return vis[T] == clc;
}
inline int dfs(int u, int a) {
  int flow = 0, f;
  if (u == T || a == 0)
    return a;
  for (int &i = cur[u]; i; i = G[i].next) {
    edge &e = G[i];
    if (e.cap && dis[e.to] == dis[u] + 1 &&
        (f = dfs(e.to, min(a, e.cap))) > 0) {
      e.cap -= f;
      flow += f;
      G[i ^ 1].cap += f;
      a -= f;
      if (a == 0)
        break;
    }
  }
  return flow;
}
inline int MaxFlow(int S, int T) {
  int flow = 0;
  while (bfs(S, T)) {
    for (int i = 1; i <= cnt; i++)
      cur[i] = head[i];
    flow += dfs(S, INF);
  }
  return flow;
}

int main(void) {
  Gcnt = 1;
  scanf("%d %d\n", &n, &m);
  S = ++cnt;
  T = ++cnt;
  for (int i = 1; i <= n; i++) {
    scanf("%s", mp[i] + 1);
    for (int j = 1; j <= m; j++)
      if (mp[i][j] == 'o') {
        in[i][j] = ++cnt;
        out[i][j] = ++cnt;
      }
  }
  for (int i = 1; i <= n; i++)
    r[i] = ++cnt;
  for (int i = 1; i <= m; i++)
    c[i] = ++cnt;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (mp[i][j] == 'S') {
        AddEdge(S, r[i], INF);
        AddEdge(S, c[j], INF);
      } else if (mp[i][j] == 'T') {
        AddEdge(r[i], T, INF);
        AddEdge(c[j], T, INF);
      } else if (mp[i][j] == 'o') {
        AddEdge(r[i], in[i][j], INF);
        AddEdge(c[j], in[i][j], INF);
        AddEdge(in[i][j], out[i][j], 1);
        AddEdge(out[i][j], r[i], INF);
        AddEdge(out[i][j], c[j], INF);
      }
  ans = MaxFlow(S, T);
  if (ans > n * m)
    ans = -1;
  cout << ans << endl;
  return 0;
}