Problem p02542 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, x, n) for (int i = x; i <= n; i++)
#define rep3(i, x, n) for (int i = x; i >= n; i--)
#define elif else if
#define sp(x) fixed << setprecision(x)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;
const double pi = acos(-1.0);
const double EPS = 1e-10;
template <typename T> bool chmax(T &x, const T &y) {
  return (x < y) ? (x = y, true) : false;
};
template <typename T> bool chmin(T &x, const T &y) {
  return (x > y) ? (x = y, true) : false;
};

template <typename T> struct Min_Cost_Flow {
  struct edge {
    int to;
    T cap, cost;
    int rev;
    edge(int to, T cap, T cost, int rev)
        : to(to), cap(cap), cost(cost), rev(rev) {}
  };

  vector<vector<edge>> es;
  vector<T> d;
  vector<int> pre_v, pre_e;
  const T INF_T;
  const int n;

  Min_Cost_Flow(int n) : INF_T(numeric_limits<T>::max()), n(n) {
    es.resize(n), d.resize(n), pre_v.resize(n), pre_e.resize(n);
  }

  void add_edge(int from, int to, T cap, T cost) {
    es[from].eb(to, cap, cost, sz(es[to]));
    es[to].eb(from, 0, -cost, sz(es[from]) - 1);
  }

  void bellman_ford(int s) {
    fill(all(d), INF_T);
    d[s] = 0;
    while (true) {
      bool update = false;
      rep(i, n) {
        if (d[i] == INF_T)
          continue;
        rep(j, sz(es[i])) {
          edge &e = es[i][j];
          if (e.cap > 0 && chmin(d[e.to], d[i] + e.cost)) {
            pre_v[e.to] = i, pre_e[e.to] = j;
            update = true;
          }
        }
      }
      if (!update)
        break;
    }
  }

  T min_cost_flow(int s, int t, T flow) {
    T ret = 0;
    while (flow > 0) {
      bellman_ford(s);
      if (d[t] == INF_T)
        return -1;
      T f = flow;
      for (int now = t; now != s; now = pre_v[now]) {
        chmin(f, es[pre_v[now]][pre_e[now]].cap);
      }
      ret += f * d[t], flow -= f;
      for (int now = t; now != s; now = pre_v[now]) {
        edge &e = es[pre_v[now]][pre_e[now]];
        e.cap -= f, es[now][e.rev].cap += f;
      }
    }
    return ret;
  }
};

int main() {
  int H, W;
  cin >> H >> W;
  string S[H];
  rep(i, H) cin >> S[i];
  int N = H * W;
  Min_Cost_Flow<ll> G(N + 2);
  int s = N, t = N + 1;
  int dx[] = {1, 0}, dy[] = {0, 1};
  int f = 0;
  rep(i, H) {
    rep(j, W) {
      if (S[i][j] == '#')
        continue;
      G.add_edge(W * i + j, t, 1, 0);
      rep(k, 2) {
        int ni = i + dx[k], nj = j + dy[k];
        if (ni >= H || nj >= W || S[ni][nj] == '#')
          continue;
        G.add_edge(W * i + j, W * ni + nj, INF, -1);
      }
      if (S[i][j] != 'o')
        continue;
      G.add_edge(s, W * i + j, 1, 0);
      f++;
    }
  }
  cout << -G.min_cost_flow(s, t, f) << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, x, n) for (int i = x; i <= n; i++)
#define rep3(i, x, n) for (int i = x; i >= n; i--)
#define elif else if
#define sp(x) fixed << setprecision(x)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;
const double pi = acos(-1.0);
const double EPS = 1e-10;
template <typename T> bool chmax(T &x, const T &y) {
  return (x < y) ? (x = y, true) : false;
};
template <typename T> bool chmin(T &x, const T &y) {
  return (x > y) ? (x = y, true) : false;
};

template <typename T> struct Min_Cost_Flow {
  struct edge {
    int to;
    T cap, cost;
    int rev;
    edge(int to, T cap, T cost, int rev)
        : to(to), cap(cap), cost(cost), rev(rev) {}
  };

  vector<vector<edge>> es;
  vector<T> d, h;
  vector<int> pre_v, pre_e;
  const T INF_T;
  const int n;

  Min_Cost_Flow(int n) : INF_T(numeric_limits<T>::max()), n(n) {
    es.resize(n), d.resize(n), h.resize(n), pre_v.resize(n), pre_e.resize(n);
  }

  void add_edge(int from, int to, T cap, T cost) {
    es[from].eb(to, cap, cost, sz(es[to]));
    es[to].eb(from, 0, -cost, sz(es[from]) - 1);
  }

  void dijkstra(int s) {
    fill(all(d), INF_T);
    using P = pair<T, int>;
    priority_queue<P, vector<P>, greater<P>> que;
    que.emplace(d[s] = 0, s);
    while (!que.empty()) {
      T p;
      int i;
      tie(p, i) = que.top();
      que.pop();
      if (p > d[i])
        continue;
      rep(j, sz(es[i])) {
        edge &e = es[i][j];
        if (e.cap > 0 && chmin(d[e.to], d[i] + e.cost + h[i] - h[e.to])) {
          pre_v[e.to] = i, pre_e[e.to] = j;
          que.emplace(d[e.to], e.to);
        }
      }
    }
  }

  T min_cost_flow(int s, int t, T flow) {
    T ret = 0;
    fill(all(h), 0);
    while (flow > 0) {
      dijkstra(s);
      if (d[t] == INF_T)
        return -1;
      rep(i, sz(es)) {
        if (h[i] == INF_T || d[i] == INF_T)
          h[i] = INF_T;
        else
          h[i] += d[i];
      }
      T f = flow;
      for (int now = t; now != s; now = pre_v[now]) {
        chmin(f, es[pre_v[now]][pre_e[now]].cap);
      }
      ret += f * h[t], flow -= f;
      for (int now = t; now != s; now = pre_v[now]) {
        edge &e = es[pre_v[now]][pre_e[now]];
        e.cap -= f, es[now][e.rev].cap += f;
      }
    }
    return ret;
  }
};

int main() {
  int H, W;
  cin >> H >> W;
  string S[H];
  rep(i, H) cin >> S[i];
  int N = H * W;
  Min_Cost_Flow<ll> G(2 * N + 2);
  int s = 2 * N, t = 2 * N + 1;
  int dx[] = {1, 0}, dy[] = {0, 1};
  int f = 0;
  rep(i, H) {
    rep(j, W) {
      G.add_edge(N + W * i + j, t, 1, 0);
      if (S[i][j] != 'o')
        continue;
      G.add_edge(s, W * i + j, 1, 0);
      f++;
      queue<pii> que;
      que.emplace(i, j);
      while (!que.empty()) {
        int x, y;
        tie(x, y) = que.front();
        que.pop();
        G.add_edge(W * i + j, N + W * x + y, 1, (H + W) - (x + y) + (i + j));
        rep(k, 2) {
          int nx = x + dx[k], ny = y + dy[k];
          if (nx >= H || ny >= W || S[nx][ny] == '#')
            continue;
          que.emplace(nx, ny);
        }
      }
    }
  }
  cout << -G.min_cost_flow(s, t, f) + (H + W) * f << endl;
}