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

#include <algorithm>
#include <iostream>
#include <queue>
#define INF 1000000000
using namespace std;
int N, M;
int po3[20], rei[2];
int res[15000000];

void pow3() {
  int tmpo = 1;
  for (int i = 0; i < 20; i++) {
    po3[i] = tmpo;
    tmpo *= 3;
  }
}

void solv(int m) {
  int abc[3] = {-1, -1, -1}, re[2];
  int tmp;
  for (int i = 0; i < N; i++) {
    tmp = (m / po3[i]) % 3;
    abc[tmp] = max(abc[tmp], i);
  }
  re[0] = re[1] = m;
  if (abc[0] > abc[1]) {
    if (abc[0] >= 0)
      re[0] = m + po3[abc[0]];
  } else {
    if (abc[1] >= 0)
      re[0] = m - po3[abc[1]];
  }
  if (abc[1] > abc[2]) {
    if (abc[1] >= 0)
      re[1] = m + po3[abc[1]];
  } else {
    if (abc[2] >= 0)
      re[1] = m - po3[abc[2]];
  }
  rei[0] = re[0];
  rei[1] = re[1];
}

int main() {
  pow3();
  int hog, piy, cnt, tmp, ress;
  queue<int> que;
  while (true) {
    cin >> N >> M;
    if (N == 0 && M == 0)
      break;
    fill(res, res + 15000000, INF);
    cnt = 0;
    for (int i = 0; i < 3; i++) {
      cin >> hog;
      for (int j = 0; j < hog; j++) {
        cin >> piy;
        piy--;
        cnt += po3[piy] * i;
      }
    }

    ress = INF;
    while (!que.empty())
      que.pop();
    que.push(cnt);
    res[cnt] = 0;
    while (!que.empty()) {
      tmp = que.front();
      que.pop();
      if (tmp == 0 || tmp == po3[N] - 1 || res[tmp] > M) {
        break;
      }
      solv(tmp);
      if (res[rei[0]] > res[tmp] + 1) {
        res[rei[0]] = res[tmp] + 1;
        que.push(rei[0]);
      }
      if (res[rei[1]] > res[tmp] + 1) {
        res[rei[1]] = res[tmp] + 1;
        que.push(rei[1]);
      }
    }
    ress = min(ress, min(res[0], res[po3[N] - 1]));
    if (ress <= M)
      cout << ress << endl;
    else
      cout << -1 << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#define INF 1000000000
using namespace std;
int N, M;
int po3[20];
int ary[15000000][2], res[15000000];

void pow3() {
  int tmpo = 1;
  for (int i = 0; i < 20; i++) {
    po3[i] = tmpo;
    tmpo *= 3;
  }
}

void solv(int m) {
  int abc[3] = {-1, -1, -1}, re[2];
  int tmp;
  for (int i = 0; i < N; i++) {
    tmp = (m / po3[i]) % 3;
    abc[tmp] = max(abc[tmp], i);
  }
  re[0] = re[1] = m;
  if (abc[0] > abc[1]) {
    if (abc[0] >= 0)
      re[0] = m + po3[abc[0]];
  } else {
    if (abc[1] >= 0)
      re[0] = m - po3[abc[1]];
  }
  if (abc[1] > abc[2]) {
    if (abc[1] >= 0)
      re[1] = m + po3[abc[1]];
  } else {
    if (abc[2] >= 0)
      re[1] = m - po3[abc[2]];
  }
  ary[m][0] = re[0];
  ary[m][1] = re[1];
}

int main() {
  pow3();
  int hog, piy, cnt, tmp, ress;
  queue<int> que;
  while (true) {
    cin >> N >> M;
    if (N == 0 && M == 0)
      break;
    for (int i = 0; i < po3[N]; i++) {
      ary[i][0] = ary[i][1] = 0;
      solv(i);
    }
    fill(res, res + 20000000, INF);
    cnt = 0;
    for (int i = 0; i < 3; i++) {
      cin >> hog;
      for (int j = 0; j < hog; j++) {
        cin >> piy;
        piy--;
        cnt += po3[piy] * i;
      }
    }

    ress = INF;
    while (!que.empty())
      que.pop();
    que.push(cnt);
    res[cnt] = 0;
    while (!que.empty()) {
      tmp = que.front();
      que.pop();
      if (tmp == 0 || tmp == po3[N] - 1 || res[tmp] > M) {
        break;
      }
      if (res[ary[tmp][0]] > res[tmp] + 1) {
        res[ary[tmp][0]] = res[tmp] + 1;
        que.push(ary[tmp][0]);
      }
      if (res[ary[tmp][1]] > res[tmp] + 1) {
        res[ary[tmp][1]] = res[tmp] + 1;
        que.push(ary[tmp][1]);
      }
    }
    ress = min(ress, min(res[0], res[po3[N] - 1]));
    if (ress <= M)
      cout << ress << endl;
    else
      cout << -1 << endl;
  }
  return 0;
}