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

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

#define INF (1e9)

typedef pair<int, int> P;

struct Q {
  int time;
  int togo;
  int status;
  int room;
  Q() {}
  Q(int a, int b, int c, int d) {
    this->time = a;
    this->togo = b;
    this->status = c;
    this->room = d;
  }
  bool operator<(const Q &rhs) const {
    return (this->time == rhs.time) ? (this->togo < rhs.togo)
                                    : (this->time < rhs.time);
  }
  bool operator>(const Q &rhs) const {
    return (this->time == rhs.time) ? (this->togo > rhs.togo)
                                    : (this->time > rhs.time);
  }
};

int main() {
  int N, M;
  int X;
  cin >> N >> M >> X;

  vector<int> T(N);
  for (int i = 0; i < N; ++i) {
    cin >> T[i];
  }

  vector<P> to[N];
  for (int i = 0; i < M; ++i) {
    int a, b, d;
    cin >> a >> b >> d;
    to[a - 1].push_back(P(d, b - 1));
    to[b - 1].push_back(P(d, a - 1));
  }

  priority_queue<Q, vector<Q>, greater<Q>> q;
  int time[N][2][X + 1];

  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < X + 1; ++k) {
        time[i][j][k] = INF;
      }
    }
  }

  q.push(Q(0, X, 0, 0)); // time, togo, status(0=cold,1=normal,2=hot), room
  time[0][0][X] = 0;
  // int cnt=0; // for debug
  while (!q.empty()) {
    Q now = q.top();
    q.pop();
    if (time[now.room][now.status / 2][now.togo] < now.time)
      continue;
    for (auto nxt : to[now.room]) {
      int nxt_togo = max(0, now.togo - nxt.first);
      if (T[nxt.second] == 1) {
        if (time[nxt.second][now.status / 2][nxt_togo] <= now.time + nxt.first)
          continue;
        time[nxt.second][now.status / 2][nxt_togo] = now.time + nxt.first;
        q.push(Q(now.time + nxt.first, nxt_togo, now.status, nxt.second));
      } else if (T[nxt.second] == now.status || nxt_togo == 0) {
        if (time[nxt.second][T[nxt.second] / 2][X] <= now.time + nxt.first)
          continue;
        time[nxt.second][T[nxt.second] / 2][X] = now.time + nxt.first;
        q.push(Q(now.time + nxt.first, X, T[nxt.second], nxt.second));
      }
    }
  }

  int ans = INF;

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < X + 1; ++j) {
      ans = min(ans, time[N - 1][i][j]);
    }
  }

  cout << ans << endl;

  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

#define INF (1e9)

typedef pair<int, int> P;

struct Q {
  int time;
  int togo;
  int status;
  int room;
  Q() {}
  Q(int a, int b, int c, int d) {
    this->time = a;
    this->togo = b;
    this->status = c;
    this->room = d;
  }
  bool operator<(const Q &rhs) const {
    return (this->time == rhs.time) ? (this->togo < rhs.togo)
                                    : (this->time < rhs.time);
  }
  bool operator>(const Q &rhs) const {
    return (this->time == rhs.time) ? (this->togo > rhs.togo)
                                    : (this->time > rhs.time);
  }
};

int main() {
  int N, M;
  int X;
  cin >> N >> M >> X;

  vector<int> T(N);
  for (int i = 0; i < N; ++i) {
    cin >> T[i];
  }

  vector<P> to[N];
  for (int i = 0; i < M; ++i) {
    int a, b, d;
    cin >> a >> b >> d;
    to[a - 1].push_back(P(d, b - 1));
    to[b - 1].push_back(P(d, a - 1));
  }

  priority_queue<Q, vector<Q>, greater<Q>> q;
  int time[N][2][X + 1];

  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < X + 1; ++k) {
        time[i][j][k] = INF;
      }
    }
  }

  q.push(Q(0, X, 0, 0)); // time, togo, status(0=cold,1=normal,2=hot), room
  time[0][0][X] = 0;
  // int cnt=0; // for debug
  while (!q.empty()) {
    Q now = q.top();
    q.pop();
    if (time[now.room][now.status / 2][now.togo] < now.time)
      continue;
    for (auto nxt : to[now.room]) {
      int nxt_togo = max(0, now.togo - nxt.first);
      if (T[nxt.second] == 1) {
        if (time[nxt.second][now.status / 2][nxt_togo] < now.time + nxt.first)
          continue;
        time[nxt.second][now.status / 2][nxt_togo] = now.time + nxt.first;
        q.push(Q(now.time + nxt.first, nxt_togo, now.status, nxt.second));
      } else if (T[nxt.second] == now.status || nxt_togo == 0) {
        if (time[nxt.second][T[nxt.second] / 2][X] < now.time + nxt.first)
          continue;
        time[nxt.second][T[nxt.second] / 2][X] = now.time + nxt.first;
        q.push(Q(now.time + nxt.first, X, T[nxt.second], nxt.second));
      }
    }
  }

  int ans = INF;

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < X + 1; ++j) {
      ans = min(ans, time[N - 1][i][j]);
    }
  }

  cout << ans << endl;

  return 0;
}