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

/*
{By GWj
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \\
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min(a, b)
#define check_max(a, b) a = max(a, b)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int GRAPH_SIZE = 50 * 50 + 100 + 20;
int pin[GRAPH_SIZE], dep[GRAPH_SIZE], s = 0, t = GRAPH_SIZE - 1;
struct EDGE {
  int u, v, c, cos;
};
vector<EDGE> e;
vector<int> each[GRAPH_SIZE];
int maxflow, mincost;
int flow[GRAPH_SIZE];
int dis[GRAPH_SIZE], inq[GRAPH_SIZE], las[GRAPH_SIZE];
bool spfa() {
  memset(inq, 0, sizeof(inq));
  memset(dis, 63, sizeof(dis));
  flow[s] = INF;
  dis[s] = 0;
  queue<int> q;
  q.push(s);
  inq[s] = 1;
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    inq[now] = 0;
    for (auto it : each[now]) {
      int to, f, c;
      to = e[it].v;
      f = e[it].c;
      c = e[it].cos;
      if (f <= 0)
        continue;
      if (dis[to] > dis[now] + c) {
        dis[to] = dis[now] + c;
        las[to] = it;
        flow[to] = min(flow[now], f);
        if (!inq[to])
          q.push(to);
        inq[to] = 1;
      }
    }
  }
  return dis[t] != INF;
}
void KM() {
  while (spfa()) {
    maxflow += flow[t];
    mincost += dis[t] * flow[t];
    int now = t;
    while (now != s) {
      e[las[now]].c -= flow[t];
      e[las[now] ^ 1].c += flow[t];
      now = e[las[now]].u;
    }
  }
}
void make_edge(int U, int V, int C, int COS) {
  EDGE tmp;
  tmp.u = U;
  tmp.v = V;
  tmp.c = C;
  tmp.cos = COS;
  e.PB(tmp);
  each[U].PB(e.size() - 1);
  swap(tmp.u, tmp.v);
  tmp.c = 0;
  tmp.cos = -COS;
  e.PB(tmp);
  each[V].PB(e.size() - 1);
}
int n, m;
string maze[51];
int walk[2][2] = {{1, 0}, {0, 1}};
bool check(int x, int y) {
  if (x <= 0 || y <= 0 || x > n || y > m)
    return 0;
  if (maze[x][y] == '#')
    return 0;
  return 1;
}
int main() {
  fastio;
  R2(n, m);
  rb(i, 1, n) R(maze[i]);
  rb(i, 1, n) maze[i] = '^' + maze[i];
  rb(i, 1, n) rb(j, 1, m) {
    int id = (i - 1) * m + j;
    if (maze[i][j] == 'o')
      make_edge(s, id, 1, 0);
    make_edge(id, t, 1, 0);
    rep(k, 2) {
      int nx, ny;
      nx = i + walk[k][0];
      ny = j + walk[k][1];
      if (check(nx, ny)) {
        make_edge(id, (nx - 1) * m + ny, INF, -1);
      }
    }
  }
  KM();
  cout << -mincost << endl;
  return 0;
}
/** 程序框架：
 *
 *
 *
 *
 **/


Error: TLE

Fixed submission:

/*
{By GWj
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \\
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min(a, b)
#define check_max(a, b) a = max(a, b)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int GRAPH_SIZE = 50 * 50 + 100 + 20;
int pin[GRAPH_SIZE], dep[GRAPH_SIZE], s = 0, t = GRAPH_SIZE - 1;
struct EDGE {
  int u, v, c, cos;
};
vector<EDGE> e;
vector<int> each[GRAPH_SIZE];
int maxflow, mincost;
int flow[GRAPH_SIZE];
int dis[GRAPH_SIZE], inq[GRAPH_SIZE], las[GRAPH_SIZE];
bool spfa() {
  memset(inq, 0, sizeof(inq));
  memset(dis, 63, sizeof(dis));
  memset(flow, 63, sizeof(flow));
  dis[s] = 0;
  queue<int> q;
  q.push(s);
  inq[s] = 1;
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    inq[now] = 0;
    for (auto it : each[now]) {
      int to, f, c;
      to = e[it].v;
      f = e[it].c;
      c = e[it].cos;
      if (f <= 0)
        continue;
      if (dis[to] > dis[now] + c) {
        dis[to] = dis[now] + c;
        las[to] = it;
        flow[to] = min(flow[now], f);
        if (!inq[to])
          q.push(to);
        inq[to] = 1;
      }
    }
  }
  return dis[t] != INF;
}
void KM() {
  while (spfa()) {
    maxflow += flow[t];
    mincost += dis[t] * flow[t];
    int now = t;
    while (now != s) {
      e[las[now]].c -= flow[t];
      e[las[now] ^ 1].c += flow[t];
      now = e[las[now]].u;
    }
  }
}
void make_edge(int U, int V, int C, int COS) {
  EDGE tmp;
  tmp.u = U;
  tmp.v = V;
  tmp.c = C;
  tmp.cos = COS;
  e.PB(tmp);
  each[U].PB(e.size() - 1);
  swap(tmp.u, tmp.v);
  tmp.c = 0;
  tmp.cos = -COS;
  e.PB(tmp);
  each[V].PB(e.size() - 1);
}
int n, m;
string maze[51];
bool vist[51][51];
int walk[2][2] = {{1, 0}, {0, 1}};
bool check(int x, int y) {
  if (x <= 0 || y <= 0 || x > n || y > m)
    return 0;
  if (maze[x][y] == '#')
    return 0;
  return 1;
}
void run(int x, int y) {
  vist[x][y] = 1;
  rep(i, 2) {
    int nx, ny;
    nx = x + walk[i][0], ny = y + walk[i][1];
    if (check(nx, ny)) {
      run(nx, ny);
    }
  }
}
int main() {
  fastio;
  R2(n, m);
  rb(i, 1, n) R(maze[i]);
  rb(i, 1, n) maze[i] = '^' + maze[i];
  int cnt = n * m;
  rb(i, 1, n) rb(j, 1, m) if (maze[i][j] == 'o') {
    memset(vist, 0, sizeof(vist));
    run(i, j);
    cnt++;
    rb(ii, 1, n) rb(jj, 1, m) if (vist[ii][jj]) {
      make_edge(cnt, ii * m - m + jj, 1, -(ii - i + jj - j));
    }
  }
  rb(i, n * m + 1, cnt) make_edge(s, i, 1, 0);
  rb(i, 1, n * m) make_edge(i, t, 1, 0);
  KM();
  cout << -mincost << endl;
  return 0;
}
/** 程序框架：
 *
 *
 *
 *
 **/