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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int maxn = 51;
const int maxm = 10100;
const int INF = 0x3ffffff;
struct Side {
  int to, next, c;
} side[maxm];
int node[maxn], top;
void add_side(int u, int v, int c) {
  side[top] = (Side){v, node[u], c};
  node[u] = top++;
}
int fee[maxn], h[maxn];
int dis[maxn][maxn];
long long vis_up[maxn][maxn];
long long vis_down[maxn][maxn];
long long vis[maxn][maxn];
int go_up[maxn][maxn];
int go_down[maxn][maxn];
int n, m;
bool inqueue[maxn];
queue<int> q;
int get_dis(int u, int dis[maxn], long long vis[maxn], bool big) {
  for (int i = 1; i <= n; i++) {
    dis[i] = INF;
    inqueue[i] = false;
  }
  dis[u] = 0;
  q.push(u);
  vis[u] = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    inqueue[u] = false;
    for (int i = node[u]; i != -1; i = side[i].next) {
      int v = side[i].to;
      if (big && h[v] < h[u])
        continue;
      if (!big && h[v] > h[u])
        continue;
      if (dis[u] + side[i].c + fee[v] < dis[v]) {
        vis[v] = vis[u] | (1ll << v);
        dis[v] = dis[u] + side[i].c + fee[v];
        if (!inqueue[v]) {
          inqueue[v] = false;
          q.push(v);
        }
      }
    }
  }
}
int main() {
  while (~scanf("%d%d", &n, &m)) {
    if (n == 0 && m == 0)
      break;
    fee[1] = fee[n] = 0;
    h[1] = 0;
    h[n] = 1000;
    top = 0;
    memset(node, -1, sizeof(node));
    for (int i = 2; i < n; i++) {
      scanf("%d%d", &fee[i], &h[i]);
    }
    for (int i = 0; i < m; i++) {
      int u, v, w;
      scanf("%d%d%d", &u, &v, &w);
      add_side(u, v, w);
    }
    for (int i = 1; i <= n; i++) {
      get_dis(i, go_up[i], vis_up[i], true);
      get_dis(i, go_down[i], vis_down[i], false);
    }
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (i == j)
          dis[i][j] = 0;
        else {
          dis[i][j] = go_up[i][j] + go_down[j][i];
          vis[i][j] = vis_up[i][j] | vis_down[j][i];
        }
      }
    }
    for (int k = 1; k <= n; k++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          int val = dis[i][k] + dis[k][j];
          for (int m = 1; m <= n; m++) {
            if ((vis[i][k] & (1LL << m)) && (vis[k][j] & (1LL << m)))
              val -= fee[m];
          }
          dis[i][j] = min(dis[i][j], val);
        }
      }
    }
    if (dis[1][n] >= INF)
      printf("-1\\n");
    else
      printf("%d\\n", dis[1][n]);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long LL;

const int oo = INT_MAX >> 1;

struct node {
  int x, y, w;
  LL s;
  node(int _x, int _y, LL _s, int _w) {
    x = _x;
    y = _y;
    s = _s;
    w = _w;
  }
  bool operator<(const node &t) const { return w > t.w; }
};
map<LL, int> f[100][100];
map<LL, bool> vis[100][100];
int c[100][100], d[100][100], w[100], h[100];

int main() {
  int N, M, i, j, x, y;
  LL s;
  while (~scanf("%d%d", &N, &M), N || M) {
    w[1] = w[N] = 0;
    h[1] = 0;
    h[N] = 1000;
    for (i = 2; i < N; i++) {
      scanf("%d%d", &w[i], &h[i]);
    }
    for (i = 1; i <= N; i++) {
      for (j = 1; j <= N; j++) {
        c[i][j] = d[i][j] = i == j ? 0 : oo;
      }
    }
    while (M--) {
      int u, v, w;
      scanf("%d%d%d", &u, &v, &w);
      if (h[u] <= h[v])
        c[u][v] = w;
      if (h[v] <= h[u])
        d[v][u] = w;
    }
    for (i = 1; i <= N; i++) {
      for (j = 1; j <= N; j++) {
        f[i][j].clear();
        vis[i][j].clear();
      }
    }
    f[1][1][1] = 0;
    priority_queue<node> Q;
    Q.push(node(1, 1, 1, 0));
    int ans = oo;
    while (!Q.empty()) {
      x = Q.top().x;
      y = Q.top().y;
      s = Q.top().s;
      Q.pop();
      if (vis[x][y].find(s) != vis[x][y].end())
        continue;
      vis[x][y][s] = 1;
      if (x == N && y == N) {
        ans = min(ans, f[x][y][s]);
      }
      for (i = 1; i <= N; i++) {
        if (h[x] <= h[i] && c[x][i] < oo) {
          LL ss = h[i] == h[x] || h[i] == h[y] ? s | (1 << i - 1) : 1 << i - 1;
          int t = f[x][y][s] + c[x][i] + (s ^ ss ? w[i] : 0);
          if (f[i][y].find(ss) == f[i][y].end() || t < f[i][y][ss]) {
            f[i][y][ss] = t;
            Q.push(node(i, y, ss, t));
          }
        }
        if (h[y] <= h[i] && d[y][i] < oo) {
          LL ss = h[i] == h[x] || h[i] == h[y] ? s | (1 << i - 1) : 1 << i - 1;
          int t = f[x][y][s] + d[y][i] + (s ^ ss ? w[i] : 0);
          if (f[x][i].find(ss) == f[x][i].end() || t < f[x][i][ss]) {
            f[x][i][ss] = t;
            Q.push(node(x, i, ss, t));
          }
        }
      }
    }
    printf("%d\\n", ans < oo ? ans : -1);
  }
}