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

#include <bits/stdc++.h>
using namespace std;
#define LOCAL
#pragma region Macros
typedef long long ll;
#define ALL(x) (x).begin(), (x).end()
const long long MOD = 1000000007;
// const long long MOD=998244353;
const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v)
    is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    os << v[i] << (i + 1 == v.size() ? "" : " ");
  }
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ',' << p.second << ')';
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << '{';
  for (auto itr = m.begin(); itr != m.end(); ++itr) {
    os << '(' << itr->first << ',' << itr->second << ')';
    if (++itr != m.end())
      os << ',';
    --itr;
  }
  os << '}';
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &s) {
  os << '{';
  for (auto itr = s.begin(); itr != s.end(); ++itr) {
    os << *itr;
    if (++itr != s.end())
      os << ',';
    --itr;
  }
  os << '}';
  return os;
}

void debug_out() { cerr << '\\n'; }
template <class Head, class... Tail>
void debug_out(Head &&head, Tail &&...tail) {
  cerr << head;
  if (sizeof...(Tail) > 0)
    cerr << ", ";
  debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                             \\
  cerr << " ";                                                                 \\
  cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]"      \\
       << '\\n';                                                                \\
  cerr << " ";                                                                 \\
  debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
#pragma endregion

template <typename T, typename E> struct PrimalDual {
  const E inf = numeric_limits<E>::max();
  struct edge {
    int to, rev;
    T cap;
    E cost;
    edge(int to, T cap, E cost, int rev)
        : to(to), cap(cap), cost(cost), rev(rev) {}
  };
  vector<vector<edge>> G;
  vector<pair<int, int>> pos;
  vector<E> h, dist;
  vector<int> prevv, preve;
  PrimalDual(int n) : G(n), h(n), dist(n), prevv(n), preve(n) {}
  int add_edge(int from, int to, T cap, E cost) {
    pos.emplace_back(from, G[from].size());
    G[from].emplace_back(to, cap, cost, G[to].size());
    G[to].emplace_back(from, 0, -cost, G[from].size() - 1);
    return pos.size() - 1;
  }
  tuple<int, int, int, int, int> get_edge(int i) {
    auto e = G[pos[i].first][pos[i].second];
    auto re = G[e.to][e.rev];
    return {pos[i].first, e.to, e.cap + re.cap, re.cap, e.cost};
  }
  vector<tuple<int, int, int, int, int>> edges() {
    vector<tuple<int, int, int, int, int>> res;
    for (int i = 0; i < pos.size(); ++i) {
      res.emplace_back(get_edge(i));
    }
    return res;
  }
  void dijkstra(int s) {
    struct P {
      E c;
      int v;
      P(E c, int v) : c(c), v(v) {}
      bool operator<(const P &rhs) const { return c > rhs.c; }
    };
    priority_queue<P> pq;
    fill(dist.begin(), dist.end(), inf);
    dist[s] = 0;
    pq.emplace(dist[s], s);
    while (!pq.empty()) {
      auto p = pq.top();
      pq.pop();
      int v = p.v;
      if (dist[v] < p.c)
        continue;
      for (int i = 0; i < G[v].size(); ++i) {
        auto &e = G[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          pq.emplace(dist[e.to], e.to);
        }
      }
    }
  }
  vector<pair<T, E>> slope(int s, int t, T lim) {
    T f = 0;
    E c = 0, pre = -1;
    vector<pair<T, E>> res;
    res.emplace_back(f, c);
    while (f < lim) {
      dijkstra(s);
      if (dist[t] == inf)
        break;
      for (int v = 0; v < G.size(); ++v)
        h[v] += dist[v];
      T d = lim - f;
      for (int v = t; v != s; v = prevv[v]) {
        d = min(d, G[prevv[v]][preve[v]].cap);
      }
      for (int v = t; v != s; v = prevv[v]) {
        auto &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
      f += d;
      c += h[t] * d;
      if (pre == h[t])
        res.pop_back();
      res.emplace_back(f, c);
      pre = c;
    }
    return res;
  }
  E min_cost_flow(int s, int t, T f) {
    auto res = slope(s, t, f).back();
    return res.first == f ? res.second : -1;
  }
  pair<T, E> min_cost_max_flow(int s, int t) {
    return slope(s, t, numeric_limits<T>::max()).back();
  }
  vector<pair<T, E>> min_cost_slope(int s, int t) {
    return slope(s, t, numeric_limits<T>::max());
  }
};

const int MAX = 110;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  vector<string> S(N);
  for (int i = 0; i < N; ++i)
    cin >> S[i];

  int s = N * M, t = s + 1, cnt = 0, ans = 0;
  PrimalDual<int, int> PD(t + 1);
  auto id = [&](int x, int y) { return x * M + y; };
  auto calc = [&](int x, int y) { return (N - 1 - x) + (M - 1 - y); };
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (S[i][j] == '#')
        continue;
      if (S[i][j] == 'o') {
        PD.add_edge(s, id(i, j), 1, 0);
        ++cnt;
        ans += calc(i, j);
      }
      PD.add_edge(id(i, j), t, 1, calc(i, j));
      for (int k = 0; k < 2; ++k) {
        int nx = i + k, ny = j + 1 - k;
        if (N <= nx || M <= ny)
          continue;
        if (S[nx][ny] == '#')
          continue;
        PD.add_edge(id(i, j), id(nx, ny), MAX, 0);
      }
    }
  }

  ans -= PD.min_cost_flow(s, t, cnt);

  cout << ans << '\\n';
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define LOCAL
#pragma region Macros
typedef long long ll;
#define ALL(x) (x).begin(), (x).end()
const long long MOD = 1000000007;
// const long long MOD=998244353;
const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v)
    is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    os << v[i] << (i + 1 == v.size() ? "" : " ");
  }
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ',' << p.second << ')';
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << '{';
  for (auto itr = m.begin(); itr != m.end(); ++itr) {
    os << '(' << itr->first << ',' << itr->second << ')';
    if (++itr != m.end())
      os << ',';
    --itr;
  }
  os << '}';
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &s) {
  os << '{';
  for (auto itr = s.begin(); itr != s.end(); ++itr) {
    os << *itr;
    if (++itr != s.end())
      os << ',';
    --itr;
  }
  os << '}';
  return os;
}

void debug_out() { cerr << '\\n'; }
template <class Head, class... Tail>
void debug_out(Head &&head, Tail &&...tail) {
  cerr << head;
  if (sizeof...(Tail) > 0)
    cerr << ", ";
  debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                             \\
  cerr << " ";                                                                 \\
  cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]"      \\
       << '\\n';                                                                \\
  cerr << " ";                                                                 \\
  debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
#pragma endregion

template <typename T, typename E> struct PrimalDual {
  const E inf = numeric_limits<E>::max();
  struct edge {
    int to, rev;
    T cap;
    E cost;
    edge(int to, T cap, E cost, int rev)
        : to(to), cap(cap), cost(cost), rev(rev) {}
  };
  vector<vector<edge>> G;
  vector<pair<int, int>> pos;
  vector<E> h, dist;
  vector<int> prevv, preve;
  PrimalDual(int n) : G(n), h(n), dist(n), prevv(n), preve(n) {}
  int add_edge(int from, int to, T cap, E cost) {
    pos.emplace_back(from, G[from].size());
    G[from].emplace_back(to, cap, cost, G[to].size());
    G[to].emplace_back(from, 0, -cost, G[from].size() - 1);
    return pos.size() - 1;
  }
  tuple<int, int, int, int, int> get_edge(int i) {
    auto e = G[pos[i].first][pos[i].second];
    auto re = G[e.to][e.rev];
    return {pos[i].first, e.to, e.cap + re.cap, re.cap, e.cost};
  }
  vector<tuple<int, int, int, int, int>> edges() {
    vector<tuple<int, int, int, int, int>> res;
    for (int i = 0; i < pos.size(); ++i) {
      res.emplace_back(get_edge(i));
    }
    return res;
  }
  void dijkstra(int s) {
    struct P {
      E c;
      int v;
      P(E c, int v) : c(c), v(v) {}
      bool operator<(const P &rhs) const { return c > rhs.c; }
    };
    priority_queue<P> pq;
    fill(dist.begin(), dist.end(), inf);
    dist[s] = 0;
    pq.emplace(dist[s], s);
    while (!pq.empty()) {
      auto p = pq.top();
      pq.pop();
      int v = p.v;
      if (dist[v] < p.c)
        continue;
      for (int i = 0; i < G[v].size(); ++i) {
        auto &e = G[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          pq.emplace(dist[e.to], e.to);
        }
      }
    }
  }
  vector<pair<T, E>> slope(int s, int t, T lim) {
    T f = 0;
    E c = 0, pre = -1;
    vector<pair<T, E>> res;
    res.emplace_back(f, c);
    while (f < lim) {
      dijkstra(s);
      if (dist[t] == inf)
        break;
      for (int v = 0; v < G.size(); ++v)
        h[v] += dist[v];
      T d = lim - f;
      for (int v = t; v != s; v = prevv[v]) {
        d = min(d, G[prevv[v]][preve[v]].cap);
      }
      for (int v = t; v != s; v = prevv[v]) {
        auto &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
      f += d;
      c += h[t] * d;
      if (pre == h[t])
        res.pop_back();
      res.emplace_back(f, c);
      pre = c;
    }
    return res;
  }
  E min_cost_flow(int s, int t, T f) {
    auto res = slope(s, t, f).back();
    return res.first == f ? res.second : -1;
  }
  pair<T, E> min_cost_max_flow(int s, int t) {
    return slope(s, t, numeric_limits<T>::max()).back();
  }
  vector<pair<T, E>> min_cost_slope(int s, int t) {
    return slope(s, t, numeric_limits<T>::max());
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  vector<string> S(N);
  cin >> S;

  auto bfs = [&](int i, int j) {
    vector<vector<int>> res(N, vector<int>(M, INF));
    queue<pair<int, int>> que;
    que.emplace(i, j);
    res[i][j] = 0;
    while (!que.empty()) {
      auto p = que.front();
      que.pop();
      int x = p.first, y = p.second;
      for (int k = 0; k < 2; ++k) {
        int nx = x + dx[k], ny = y + dy[k];
        if (N <= nx || M <= ny)
          continue;
        if (S[nx][ny] == '#')
          continue;
        res[nx][ny] = res[x][y] + 1;
        que.emplace(nx, ny);
      }
    }
    return res;
  };

  PrimalDual<int, ll> PD(2 * N * M + 2);
  int s = 2 * N * M, t = s + 1, cnt = 0;
  auto id = [&](int x, int y) { return M * x + y; };
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (S[i][j] != 'o')
        continue;
      ++cnt;
      PD.add_edge(s, id(i, j), 1, 0);
      vector<vector<int>> dist = bfs(i, j);
      for (int k = 0; k < N; ++k) {
        for (int l = 0; l < M; ++l) {
          if (dist[k][l] == INF)
            continue;
          PD.add_edge(id(i, j), N * M + id(k, l), 1, INF - dist[k][l]);
        }
      }
    }
  }

  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (S[i][j] != '#') {
        PD.add_edge(N * M + id(i, j), t, 1, 0);
      }
    }
  }

  ll ans = PD.min_cost_flow(s, t, cnt);

  cout << (ll)INF * cnt - ans << '\\n';
}