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

#include <bits/stdc++.h>
#define N 55
using namespace std;
const int INF = 1e9;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef priority_queue<PP, vector<PP>, greater<PP>> PQ;
int n, fee[N], height[N], G[2][N][N];
int D[N][N][1 << 10];

int Push(PQ &Q, int cost, int p1, int p2, int bit) {
  if (D[p1][p2][bit] <= cost)
    return 0;
  D[p1][p2][bit] = cost;
  Q.push(PP(P(cost, p1), P(p2, bit)));
  return 1;
}

int dijkstra() {

  int idx[N];
  map<int, int> cnt;
  for (int i = 0; i < n; i++)
    idx[i] = cnt[height[i]]++;

  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      for (int k = 0; k < (1 << 10); k++)
        D[i][j][k] = INF;
  PQ Q;
  Push(Q, 0, 0, 0, 1 << idx[0]);

  while (!Q.empty()) {
    PP t = Q.top();
    Q.pop();
    int cost = t.first.first;
    int p1 = t.first.second;
    int p2 = t.second.first;
    int bit = t.second.second;
    if (D[p1][p2][bit] < cost)
      continue;
    if (p1 == n - 1 && p2 == n - 1)
      return cost;

    for (int to = 0; to < n; to++) {
      int ncost = cost + G[0][p1][to] + fee[to];
      int nbit = bit;
      if (height[p1] == height[to] && bit >> idx[to] & 1)
        ncost -= fee[to];
      if (height[p1] == height[to])
        nbit |= 1 << idx[to];
      else
        nbit = 1 << idx[to];
      Push(Q, ncost, to, p2, nbit);
    }

    for (int to = 0; to < n; to++) {
      int ncost = cost + G[1][p2][to] + fee[to];
      if (height[p1] == height[to] && bit >> idx[to] & 1)
        ncost -= fee[to];
      Push(Q, ncost, p1, to, bit);
    }
  }
  return -1;
}

signed main() {
  while (1) {
    int m;
    cin >> n >> m;
    if (n == 0 && m == 0)
      return 0;
    memset(fee, 0, sizeof(fee));
    memset(height, 0, sizeof(height));
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        G[0][i][j] = G[1][i][j] = INF;

    height[0] = 0;
    height[n - 1] = 1000;
    for (int i = 1; i < n - 1; i++)
      cin >> fee[i] >> height[i];

    for (int i = 0; i < m; i++) {
      int a, b, c;
      cin >> a >> b >> c;
      a--, b--;
      if (height[a] <= height[b])
        Min(G[0][a][b], c);
      if (height[a] >= height[b])
        Min(G[1][b][a], c);
    }
    cout << dijkstra() << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define N 51
using namespace std;
const int INF = 1LL << 55;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef priority_queue<PP, vector<PP>, greater<PP>> PQ;
int n, fee[N], height[N];
int G[2][N][N];

int D[N][N][1 << 10];

int Push(PQ &Q, int cost, int p1, int p2, int bit) {
  if (D[p1][p2][bit] <= cost)
    return 0;
  D[p1][p2][bit] = cost;
  Q.push(PP(P(cost, p1), P(p2, bit)));
  return 1;
}

int dijkstra() {

  int idx[N];
  map<int, int> cnt;
  for (int i = 0; i < n; i++)
    idx[i] = cnt[height[i]]++;

  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      for (int k = 0; k < (1 << 10); k++)
        D[i][j][k] = INF;
  PQ Q;
  Push(Q, 0, 0, 0, 0);

  while (!Q.empty()) {
    PP t = Q.top();
    Q.pop();
    int cost = t.first.first;
    int p1 = t.first.second;
    int p2 = t.second.first;
    int bit = t.second.second;
    if (D[p1][p2][bit] < cost)
      continue;
    if (p1 == n - 1 && p2 == n - 1)
      return cost;

    for (int to = 0; to < n; to++) {
      int ncost = cost + G[0][p1][to] + fee[to];
      int nbit = bit;
      if (height[p2] == height[to])
        nbit |= 1 << idx[to];
      else if (height[to] != height[p2])
        nbit = 1 << idx[to];
      Push(Q, ncost, to, p2, nbit);
    }

    for (int to = 0; to < n; to++) {
      int ncost = cost + G[1][p2][to] + fee[to];
      int nbit = bit;
      if (height[p1] == height[to] && bit >> idx[to] & 1)
        ncost -= fee[to];
      Push(Q, ncost, p1, to, nbit);
    }
  }
  return -1;
}

signed main() {
  while (1) {
    int m;
    cin >> n >> m;
    if (n == 0 && m == 0)
      return 0;
    height[0] = 0;
    height[n - 1] = 1000;
    for (int i = 1; i < n - 1; i++)
      cin >> fee[i] >> height[i];

    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        G[0][i][j] = G[1][i][j] = INF;

    for (int i = 0; i < m; i++) {
      int a, b, c;
      cin >> a >> b >> c;
      a--, b--;
      if (height[a] <= height[b])
        Min(G[0][a][b], c);
      if (height[a] >= height[b])
        Min(G[1][b][a], c);
    }
    cout << dijkstra() << endl;
  }
  return 0;
}