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

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define debug(x) cout << "debug " << x << endl;
const int INF = 100000000;
using namespace std;

const int N = 200;

struct point {
  int x, y;
};
int dy[4] = {0, 1, 0, -1}, dx[4] = {1, 0, -1, 0};
char m[N][N];

int bfs(int h, int w, point start, point goal, int dis[N][N]) {
  queue<point> q;

  dis[start.y][start.x] = 0;
  q.push(start);

  point u;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    rep(i, 4) {
      point next;
      next.x = u.x + dx[i];
      next.y = u.y + dy[i];
      if (next.y >= h || next.y < 0 || next.x >= w || next.x < 0)
        continue;
      if (dis[next.y][next.x] == -1 && m[next.y][next.x] != '#') {
        dis[next.y][next.x] = dis[u.y][u.x] + 1;
        q.push(next);
      }
    }
  }
  return dis[goal.y][goal.x];
}

bool check(int dis[N][N], vector<point> v, int p) {
  rep(i, v.size()) {
    if (dis[v[i].y][v[i].x] <= p)
      return 1;
  }
  return 0;
}

int main() {
  int h, w;
  int dis[N][N];
  point princess, patch;
  vector<point> soldiers;

  scanf("%d%d", &h, &w);
  rep(i, h) {
    scanf("%s", m[i]);
    rep(j, w) {
      if (m[i][j] == '%')
        patch = {j, i};
      else if (m[i][j] == '@')
        princess = {j, i};
      else if (m[i][j] == '$') {
        point temp = {j, i};
        soldiers.emplace_back(temp);
      }
    }
  }

  memset(dis, -1, sizeof(dis));
  int p = bfs(h, w, princess, patch, dis);

  memset(dis, -1, sizeof(dis));
  bfs(h, w, patch, patch, dis); // dis???patch??????????????¢???????????????

  if (check(dis, soldiers, p))
    printf("No\\n");
  else
    printf("Yes\\n");
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define debug(x) cout << "debug " << x << endl;
const int INF = 100000000;
using namespace std;

const int N = 200;

struct point {
  int x, y;
};
int dy[4] = {0, 1, 0, -1}, dx[4] = {1, 0, -1, 0};
char m[N][N];
int p = INF, s = INF;

int bfs(int h, int w, point start, point goal) {
  int dis[N][N];
  queue<point> q;
  memset(dis, -1, sizeof(dis));

  dis[start.y][start.x] = 0;
  q.push(start);

  point u;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    rep(i, 4) {
      point next;
      next.x = u.x + dx[i];
      next.y = u.y + dy[i];
      if (next.y >= h || next.y < 0 || next.x >= w || next.x < 0)
        continue;
      if (dis[next.y][next.x] == -1 && m[next.y][next.x] != '#') {
        dis[next.y][next.x] = dis[u.y][u.x] + 1;
        if (dis[next.y][next.x] > p || dis[next.y][next.x] > s)
          break;
        if (next.y == goal.y && next.x == goal.x)
          return dis[goal.y][goal.x];
        q.push(next);
      }
    }
  }
  return INF;
}

int main() {
  int h, w;
  point start, goal;

  scanf("%d%d", &h, &w);
  rep(i, h) {
    scanf("%s", m[i]);
    rep(j, w) {
      if (m[i][j] == '%')
        goal = {j, i};
    }
  }

  rep(i, h) {
    rep(j, w) {
      if (m[i][j] == '@') {
        start = {j, i};
        p = bfs(h, w, start, goal);
      } else if (m[i][j] == '$') {
        start = {j, i};
        s = min(bfs(h, w, start, goal), s);
      }
      // cout << p << ' ' << s << endl;;
    }
  }
  if (p < s)
    printf("Yes\\n");
  else
    printf("No\\n");
}