Problem p03436 (C++)

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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;

template <typename T> void out(T x) {
  cout << x << endl;
  exit(0);
}
#define watch(x) cout << (#x) << " is " << (x) << endl

typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int maxn = 55;
const int inf = 0x3f3f3f3f;

int n, m;
string g[maxn];
int dist[maxn][maxn];
pair<int, int> prv[maxn][maxn];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> g[i];
  }

  memset(dist, inf, sizeof dist);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      prv[i][j].first = -1;
      prv[i][j].second = -1;
    }
  }

  queue<pair<pair<int, int>, pair<int, pair<int, int>>>> q;
  q.push({{0, 0}, {0, {-1, -1}}});

  while (!q.empty()) {
    auto cur = q.front();
    q.pop();
    auto at = cur.first;
    int dst = cur.second.first;
    auto previous = cur.second.second;
    dist[at.first][at.second] = dst;
    prv[at.first][at.second] = previous;

    vector<pair<int, int>> moves = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
    for (auto mo : moves) {
      int x = mo.first + at.first;
      int y = mo.second + at.second;
      if (x < 0 || y < 0 || x >= n || y >= m || dist[x][y] <= dst + 1 ||
          g[x][y] == '#')
        continue;
      q.push({{x, y}, {dst + 1, at}});
    }
  }

  if (dist[n - 1][m - 1] == inf)
    out(-1);

  int x = n - 1;
  int y = m - 1;
  while (x != -1 && y != -1) {
    g[x][y] = '#';
    int x2 = prv[x][y].first;
    int y2 = prv[x][y].second;
    x = x2;
    y = y2;
  }

  int ans = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      ans += (g[i][j] == '.');
    }
  }

  out(ans);

  return 0;
}


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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;

template <typename T> void out(T x) {
  cout << x << endl;
  exit(0);
}
#define watch(x) cout << (#x) << " is " << (x) << endl

typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int maxn = 55;
const int inf = 0x3f3f3f3f;

int n, m;
string g[maxn];
int dist[maxn][maxn];
pair<int, int> prv[maxn][maxn];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> g[i];
  }

  memset(dist, inf, sizeof dist);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      prv[i][j].first = -1;
      prv[i][j].second = -1;
    }
  }

  queue<pair<pair<int, int>, pair<int, pair<int, int>>>> q;
  q.push({{0, 0}, {0, {-1, -1}}});

  while (!q.empty()) {
    auto cur = q.front();
    q.pop();
    auto at = cur.first;
    int dst = cur.second.first;
    auto previous = cur.second.second;
    dist[at.first][at.second] = dst;
    prv[at.first][at.second] = previous;

    vector<pair<int, int>> moves = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
    for (auto mo : moves) {
      int x = mo.first + at.first;
      int y = mo.second + at.second;
      if (x < 0 || y < 0 || x >= n || y >= m || dist[x][y] <= dst + 1 ||
          g[x][y] == '#')
        continue;
      dist[x][y] = dst + 1;
      q.push({{x, y}, {dst + 1, at}});
    }
  }

  if (dist[n - 1][m - 1] == inf)
    out(-1);

  int x = n - 1;
  int y = m - 1;
  while (x != -1 && y != -1) {
    g[x][y] = '#';
    int x2 = prv[x][y].first;
    int y2 = prv[x][y].second;
    x = x2;
    y = y2;
  }

  int ans = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      ans += (g[i][j] == '.');
    }
  }

  out(ans);

  return 0;
}