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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = 1; i < n; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  REP(i, v.size()) cout << #v << "[" << i << "]: " << v[i] << endl
#define ALL(a) (a).begin(), (a).end()

const int INF = 1e9;

const int MAX_R = 30;
const int MAX_C = 30;
const int MAX_V = 900;

int R, C;
int V;

// dijkstra
int cost[MAX_V][MAX_V];
int dist[MAX_V];
bool used[MAX_V];
void dijkstra(int s) {
  fill(dist, dist + V, INF);
  fill(used, used + V, false);
  dist[s] = 0;
  while (true) {
    int v = -1;
    REP(u, V) if (!used[u] && (v == -1 || dist[u] < dist[v])) v = u;
    if (v == -1)
      break;
    used[v] = true;
    REP(u, V) dist[u] = min(dist[u], dist[v] + cost[v][u]);
  }
}

int mp[MAX_R][MAX_C];
int NONE = 0, WALL = 1, ALLY = 2, ENEMY = 3;
int SX, SY, GX, GY;

int main() {
  cin >> R >> C;
  V = R * C;
  REP(i, R) {
    string s;
    cin >> s;
    REP(j, C) {
      char c = s[j];
      if (c == '.')
        mp[i][j] = NONE;
      if (c == '#')
        mp[i][j] = WALL;
      if (c == 'o')
        mp[i][j] = ALLY;
      if (c == 'x')
        mp[i][j] = ENEMY;
      if (c == 'S') {
        mp[i][j] = NONE;
        SX = j;
        SY = i;
      }
      if (c == 'G') {
        mp[i][j] = NONE;
        GX = j;
        GY = i;
      }
    }
  }

  // fill(cost,cost+MAX_V*MAX_V,INF);
  REP(i, MAX_V) REP(j, MAX_V) cost[i][j] = INF;
  int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
  REP(y, R) REP(x, C) {
    int now = mp[y][x];
    if (now == WALL)
      continue;
    if (GY == y && GX == x)
      continue;
    REP(d, 4) {
      int ny = y + dy[d], nx = x + dx[d];
      if (nx < 0 || ny < 0 || nx >= C || ny >= R)
        continue;
      int next = mp[ny][nx];
      if (next == WALL)
        continue;
      if (next == NONE)
        cost[y * C + x][ny * C + nx] = 2;
      if (next == ALLY)
        cost[y * C + x][ny * C + nx] = 1;
      REP(i, 3) {
        if (nx < 0 || ny < 0 || nx >= C || ny >= R)
          break;
        next = mp[ny][nx];
        if (next == WALL)
          break;
        cost[y * C + x][ny * C + nx] = min(cost[y * C + x][ny * C + nx], 3 + i);
        ny += dy[d];
        nx += dx[d];
      }
    }
  }
  dijkstra(SY * C + SX);
  cout << dist[GY * C + GX] << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef vector<vi> grid;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = 1; i < n; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  REP(i, v.size()) cout << #v << "[" << i << "]: " << v[i] << endl
#define ALL(a) (a).begin(), (a).end()

int R, C;
int NONE = 0, WALL = 1, ALLY = 2, ENEMY = 3, VISITED = -1;
int GX, GY;
// int vx[4] = {1,0,-1,0};
// int vy[4] = {0,1,0,-1};
int INF = 1e8;

void pg(grid x) {
  REP(i, R) {
    REP(j, C) {
      if (x[i][j] != VISITED)
        cout << x[i][j] << " ";
      else
        cout << "V ";
    }
    cout << endl;
  }
  cout << endl;
}

int dfs(int x, int y, grid g) {
  if (x < 0 || y < 0 || x >= C || y >= R)
    return INF;
  if (g[x][y] == WALL)
    return INF;
  if (g[x][y] == ENEMY)
    return INF;
  if (g[x][y] == VISITED)
    return INF;
  if (x == GX && y == GY)
    return 0;
  // cout << x << y << " " << g[x][y] << endl;
  int result = INF;
  int vx[4], vy[4];
  if (GX >= x && GY >= y) {
    vx[0] = 1;
    vx[1] = 0;
    vx[2] = -1;
    vx[3] = 0;
    vy[0] = 0;
    vy[1] = 1;
    vy[2] = 0;
    vy[3] = -1;
  } else if (GX >= x && GY < y) {
    vx[0] = 1;
    vx[1] = 0;
    vx[2] = -1;
    vx[3] = 0;
    vy[0] = 0;
    vy[1] = -1;
    vy[2] = 0;
    vy[3] = 1;
  } else if (GX < x && GY >= y) {
    vx[0] = -1;
    vx[1] = 0;
    vx[2] = 1;
    vx[3] = 0;
    vy[0] = 0;
    vy[1] = 1;
    vy[2] = 0;
    vy[3] = -1;
  } else if (GX < x && GY < y) {
    vx[0] = -1;
    vx[1] = 0;
    vx[2] = 1;
    vx[3] = 0;
    vy[0] = 0;
    vy[1] = -1;
    vy[2] = 0;
    vy[3] = 1;
  }
  // pg(g);
  REP(i, 4) {
    if (i >= 2 && result != INF)
      break;
    int nx = x + vx[i], ny = y + vy[i];
    if (nx < 0 || ny < 0 || nx >= C || ny >= R)
      continue;
    int next = g[nx][ny];
    if (nx == GX && ny == GY) {
      if (next == NONE)
        return 2;
      if (next == ALLY)
        return 1;
    }
    if (next == WALL)
      continue;
    if (next == VISITED)
      continue;
    if (next == ALLY) {
      grid ng = g;
      ng[x][y] = VISITED;
      result = min(result, 1 + dfs(nx, ny, ng));
    }
    if (next == ENEMY) {
      grid ng = g;
      int nnx = x, nny = y;
      REP(j, 3) {
        nnx += vx[i];
        nny += vy[i];
        if (nnx < 0 || nny < 0 || nnx >= C || nny >= R)
          break;
        int nnext = g[nnx][nny];
        if (nnext == WALL)
          break;
        if (nnext != VISITED)
          ng[nnx][nny] = ALLY;
      }
      ng[x][y] = VISITED;
      result = min(result, 3 + dfs(nx, ny, ng));
    }
    if (next == NONE) {
      grid ng = g;
      ng[x][y] = VISITED;
      result = min(result, 2 + dfs(nx, ny, ng));
      int nnx = x, nny = y;
      int cnt = 0;
      REP(j, 3) {
        nnx += vx[i];
        nny += vy[i];
        if (nnx < 0 || nny < 0 || nnx >= C || nny >= R)
          break;
        int nnext = g[nnx][nny];
        if (nnext == WALL)
          break;
        if (nnext == VISITED)
          break;
        if (nnext == ALLY)
          break;
        ng[nnx][nny] = ALLY;
        ++cnt;
      }
      if (cnt == 3)
        result = min(result, 3 + dfs(nx, ny, ng));
    }
  }
  return result;
}

int main() {
  cin >> R >> C;
  grid g(C, vi(R));
  int x, y;
  REP(i, R) {
    string s;
    cin >> s;
    REP(j, C) {
      char c = s[j];
      if (c == '.')
        g[j][i] = NONE;
      if (c == '#')
        g[j][i] = WALL;
      if (c == 'o')
        g[j][i] = ALLY;
      if (c == 'x')
        g[j][i] = ENEMY;
      if (c == 'S') {
        g[j][i] = NONE;
        x = j;
        y = i;
      }
      if (c == 'G') {
        g[j][i] = NONE;
        GX = j, GY = i;
      }
    }
  }
  cout << dfs(x, y, g) << endl;
  return 0;
}