Problem p01419 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

enum { PER, ON, OFF };
const int INF = 1 << 30;
const int dc[] = {1, 0, -1, 0};
const int dr[] = {0, 1, 0, -1};

typedef struct {
  int p[3];
} Light;

class RC {
public:
  int r, c;
  RC(int _r = 0, int _c = 0) : r(_r), c(_c) {}
};

int main() {
  int R, C, M;
  while (~scanf("%d %d %d", &R, &C, &M)) {
    vector<string> office(R);
    for (int r = 0; r < R; ++r)
      cin >> office[r];

    vector<vector<Light>> cost(R, vector<Light>(C));
    for (int i = 0; i < 3; ++i) {
      for (int r = 0; r < R; ++r) {
        for (int c = 0; c < C; ++c)
          scanf("%d", &cost[r][c].p[i]);
      }
    }

    vector<RC> task(M);
    for (int i = 0; i < M; ++i)
      scanf("%d %d", &task[i].r, &task[i].c);

    vector<vector<vector<vector<int>>>> path(
        R, vector<vector<vector<int>>>(
               C, vector<vector<int>>(R, vector<int>(C, INF))));
    for (int r = 0; r < R; ++r) {
      for (int c = 0; c < C; ++c) {
        if (office[r][c] == '#')
          continue;

        path[r][c][r][c] = 0;
        queue<RC> que;
        vector<vector<int>> visited(R, vector<int>(C, 0));
        que.push(RC(r, c));
        while (!que.empty()) {
          RC rc = que.front();
          que.pop();
          visited[rc.r][rc.c] = 1;
          for (int d = 0; d < 4; ++d) {
            int rr = rc.r + dr[d];
            int cc = rc.c + dc[d];
            if (rr < 0 || rr >= R || cc < 0 || cc >= C ||
                office[rr][cc] == '#' || visited[rr][cc])
              continue;
            path[r][c][rr][cc] = path[r][c][rc.r][rc.c] + 1;
            que.push(RC(rr, cc));
          }
        }
      }
    }

    int time = 0;
    vector<vector<vector<int>>> pass(R, vector<vector<int>>(C));
    for (int i = 0; i < M - 1; ++i) {
      RC s = task[i], t = task[i + 1];
      while (s.r != t.r || s.c != t.c) {
        pass[s.r][s.c].push_back(time++);
        for (int d = 0; d < 4; ++d) {
          int rr = s.r + dr[d];
          int cc = s.c + dc[d];
          if (rr < 0 || rr >= R || cc < 0 || cc >= C)
            continue;
          if (path[rr][cc][t.r][t.c] + 1 == path[s.r][s.c][t.r][t.c]) {
            s.r = rr;
            s.c = cc;
            break;
          }
        }
      }
    }
    // fix
    pass[task[M - 1].r][task[M - 1].c].push_back(time);

    int ans = 0;
    for (int r = 0; r < R; ++r) {
      for (int c = 0; c < C; ++c) {
        if (pass[r][c].empty())
          continue;

        const int on_off = cost[r][c].p[ON] + cost[r][c].p[OFF];
        ans += on_off * pass[r][c].size();

        for (unsigned int i = 0; i < pass[r][c].size() - 1; ++i) {
          const int per =
              (pass[r][c][i + 1] - pass[r][c][i]) * cost[r][c].p[PER];
          if (per < on_off)
            ans -= (on_off - per);
        }
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

typedef struct {
  int c[3];
} Light;

class Point {
public:
  int r, c;
  Point(int _r = 0, int _c = 0) : r(_r), c(_c) {}
};

class State {
public:
  int t;
  Point p;
  vector<Point> path;
  State() {}
  State(int _t, Point _p) : t(_t), p(_p) {}
  void update(Point p) {
    this->t += 1;
    this->p = p;
  }
  bool operator<(const State &st) const { return this->t > st.t; }
};

enum { PER, ON, OFF };
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

int main() {
  int R, C, M;
  while (~scanf("%d %d %d", &R, &C, &M)) {
    vector<string> office(R);
    for (int i = 0; i < R; ++i)
      cin >> office[i];

    vector<vector<Light>> cost(R, vector<Light>(C));
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < R; ++j) {
        for (int k = 0; k < C; ++k)
          scanf("%d", &cost[j][k].c[i]);
      }
    }

    vector<Point> task(M);
    for (int i = 0; i < M; ++i)
      scanf("%d %d", &task[i].r, &task[i].c);

    int time = 0;
    vector<vector<vector<int>>> pass(R, vector<vector<int>>(C));
    for (int i = 0; i < M - 1; ++i) {
      State st, tmp;
      priority_queue<State> que;
      que.push(State(time, Point(task[i].r, task[i].c)));

      while (!que.empty()) {
        st = que.top();
        que.pop();

        st.path.push_back(st.p);
        if (st.p.r == task[i + 1].r && st.p.c == task[i + 1].c)
          break;

        for (int j = 0; j < 4; ++j) {
          tmp = st;
          Point p(st.p.r + dy[j], st.p.c + dx[j]);
          if (p.r < 0 || p.r >= R || p.c < 0 || p.c >= C ||
              office[p.r][p.c] == '#')
            continue;
          tmp.update(p);
          que.push(tmp);
        }
      }

      for (unsigned int j = 0; j < st.path.size() - 1; ++j) {
        const Point &p = st.path[j];
        pass[p.r][p.c].push_back(time + j);
      }
      time = st.t;
    }

    // fix
    pass[task[task.size() - 1].r][task[task.size() - 1].c].push_back(time);

    int ans = 0;
    for (int i = 0; i < R; ++i) {
      for (int j = 0; j < C; ++j) {
        if (pass[i][j].empty())
          continue;
        const int ON_OFF = cost[i][j].c[ON] + cost[i][j].c[OFF];
        ans += ON_OFF * pass[i][j].size();
        if (pass[i][j].size() == 1)
          continue;
        for (unsigned int k = 0; k < pass[i][j].size() - 1; ++k) {
          const int per =
              (pass[i][j][k + 1] - pass[i][j][k]) * cost[i][j].c[PER];
          if (per < ON_OFF) {
            ans -= ON_OFF;
            ans += per;
          }
        }
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}