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

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int ROOM_NUM = 15;
int tab[1 << ROOM_NUM][ROOM_NUM];
pair<int, int> from[1 << ROOM_NUM][ROOM_NUM];

int n, m;
int door[ROOM_NUM][ROOM_NUM];
int switches[ROOM_NUM];

const int INF = 1e9;

struct s {
  int lights;
  int doctor;
  int cost;
  s() {
    lights = -1;
    doctor = -1;
    cost = -1;
  }
  s(int l, int d, int c) {
    lights = l;
    doctor = d;
    cost = c;
  }
};

void search(const int arg_lights, const int arg_doctor) {
  queue
 q;
  q.push(s(arg_lights, arg_doctor, 0));
  while (!q.empty()) {
    s tmp;
    tmp = q.front();
    q.pop();
    tab[tmp.lights][tmp.doctor] = tmp.cost;
    for (int i = 0; i < n; i++) {
      if ((switches[tmp.doctor] & (1 << i)) && i != tmp.doctor) {
        if (tab[tmp.lights ^ (1 << i)][tmp.doctor] == INF) {
          q.push(s(tmp.lights ^ (1 << i), tmp.doctor, tmp.cost + 1));
          from[tmp.lights ^ (1 << i)][tmp.doctor] =
              pair<int, int>(tmp.lights, tmp.doctor);
          tab[tmp.lights ^ (1 << i)][tmp.doctor] = -1;
        }
      }
      if (door[tmp.doctor][i] && (tmp.lights & (1 << i)) && i != tmp.doctor) {
        if (tab[tmp.lights][i] == INF) {
          q.push(s(tmp.lights, i, tmp.cost + 1));
          from[tmp.lights][i] = pair<int, int>(tmp.lights, tmp.doctor);
          tab[tmp.lights][i] = -1;
        }
      }
    }
  }
}

struct step {
  int step_type;
  int R;
  step() {
    step_type = -1;
    R = -1;
  }
  step(int st, int r) {
    step_type = st;
    R = r;
  }

  static const int MOVE;
  static const int SWITCH;
  static const int ON;

  bool operator==(const step obj) const {
    return obj.step_type == step_type && obj.R == R;
  }
  bool operator<(const step obj) const { return R < obj.R; }
};

const int step::MOVE = 1;
const int step::SWITCH = 2;
const int step::ON = 4;

int main() {
  while (cin >> n >> m, n || m) {
    // init
    for (int i = 0; i < (1 << ROOM_NUM); i++) {
      for (int j = 0; j < ROOM_NUM; j++) {
        tab[i][j] = INF;
        from[i][j] = pair<int, int>(-1, -1);
      }
    }
    for (int i = 0; i < ROOM_NUM; i++) {
      for (int j = 0; j < ROOM_NUM; j++)
        door[i][j] = 0;
      switches[i] = 0;
    }
    // input
    for (int i = 0; i < m; i++) {
      int s, t;
      cin >> s >> t;
      door[s - 1][t - 1] = 1;
      door[t - 1][s - 1] = 1;
    }

    int lightstatus = 0;
    for (int i = 0; i < n; i++) {
      int tmp;
      cin >> tmp;
      lightstatus |= tmp << i;
    }
    for (int i = 0; i < n; i++) {
      int k;
      cin >> k;
      for (int j = 0; j < k; j++) {
        int tmp;
        cin >> tmp;
        switches[i] |= 1 << (tmp - 1);
      }
    }

    // tab[lightstatus][0] = 0;
    search(lightstatus, 0);

    if (tab[1 << (n - 1)][n - 1] < INF) {
      vector<pair<int, int>> path;
      pair<int, int> tmp(1 << (n - 1), n - 1);
      while (tmp != pair<int, int>(lightstatus, 0)) {
        path.push_back(tmp);
        tmp = from[tmp.first][tmp.second];
        if (tmp == pair<int, int>(-1, -1))
          abort();
      }
      path.push_back(tmp);
      reverse(path.begin(), path.end());

      cout << "You can go home in " << tab[1 << (n - 1)][n - 1] << " steps."
           << endl;
      ;

      vector<step> ans;
      for (int i = 1; i < path.size(); i++) {
        if (path[i - 1].second != path[i].second)
          ans.push_back(step(step::MOVE, path[i].second));
        else {
          int r;
          for (int j = 0; j < n; j++) {
            if ((path[i - 1].first ^ path[i].first) & (1 << j))
              r = j;
          }
          if (path[i].first & (1 << r)) {
            ans.push_back(step(step::SWITCH | step::ON, r));
          } else {
            ans.push_back(step(step::SWITCH, r));
          }
        }
      }
      for (int i = 0; i < ans.size(); i++) {
        if (ans[i].step_type == step::MOVE)
          cout << "Move to room " << ans[i].R + 1 << "." << endl;
        else {
          vector<step> v;
          for (; i < ans.size() && (ans[i].step_type & step::SWITCH); i++)
            v.push_back(ans[i]);
          sort(v.begin(), v.end());
          for (int j = 0; j < v.size(); j++) {
            if (v[j].step_type & step::ON)
              cout << "Switch on room " << v[j].R + 1 << "." << endl;
            else
              cout << "Switch off room " << v[j].R + 1 << "." << endl;
          }
          i--;
        }
      }
    } else {
      bool flg = false;
      for (int i = 0; i < (1 << n); i++) {
        if ((i & (1 << (n - 1))) && tab[i][n - 1] < INF) {
          flg = true;
          break;
        }
      }
      if (flg)
        cout << "You can not switch off all lights." << endl;
      else
        cout << "Help me!" << endl;
    }
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int ROOM_NUM = 15;
int tab[1 << ROOM_NUM][ROOM_NUM];
pair<int, int> from[1 << ROOM_NUM][ROOM_NUM];

int n, m;
int door[ROOM_NUM][ROOM_NUM];
int switches[ROOM_NUM];

const int INF = 1e9;

struct s {
  int lights;
  int doctor;
  int cost;
  s() {
    lights = -1;
    doctor = -1;
    cost = -1;
  }
  s(int l, int d, int c) {
    lights = l;
    doctor = d;
    cost = c;
  }
};

void search(const int arg_lights, const int arg_doctor) {
  queue
 q;
  q.push(s(arg_lights, arg_doctor, 0));
  while (!q.empty()) {
    s tmp;
    tmp = q.front();
    q.pop();
    tab[tmp.lights][tmp.doctor] = tmp.cost;
    for (int i = 0; i < n; i++) {
      if ((switches[tmp.doctor] & (1 << i)) && i != tmp.doctor) {
        if (tab[tmp.lights ^ (1 << i)][tmp.doctor] == INF) {
          q.push(s(tmp.lights ^ (1 << i), tmp.doctor, tmp.cost + 1));
          from[tmp.lights ^ (1 << i)][tmp.doctor] =
              pair<int, int>(tmp.lights, tmp.doctor);
        }
      }
      if (door[tmp.doctor][i] && (tmp.lights & (1 << i)) && i != tmp.doctor) {
        if (tab[tmp.lights][i] == INF) {
          q.push(s(tmp.lights, i, tmp.cost + 1));
          from[tmp.lights][i] = pair<int, int>(tmp.lights, tmp.doctor);
        }
      }
    }
  }
}

struct step {
  int step_type;
  int R;
  step() {
    step_type = -1;
    R = -1;
  }
  step(int st, int r) {
    step_type = st;
    R = r;
  }

  static const int MOVE;
  static const int SWITCH;
  static const int ON;

  bool operator==(const step obj) const {
    return obj.step_type == step_type && obj.R == R;
  }
  bool operator<(const step obj) const { return R < obj.R; }
};

const int step::MOVE = 1;
const int step::SWITCH = 2;
const int step::ON = 4;

int main() {
  while (cin >> n >> m, n || m) {
    // init
    for (int i = 0; i < (1 << ROOM_NUM); i++) {
      for (int j = 0; j < ROOM_NUM; j++) {
        tab[i][j] = INF;
        from[i][j] = pair<int, int>(-1, -1);
      }
    }
    for (int i = 0; i < ROOM_NUM; i++) {
      for (int j = 0; j < ROOM_NUM; j++)
        door[i][j] = 0;
      switches[i] = 0;
    }
    // input
    for (int i = 0; i < m; i++) {
      int s, t;
      cin >> s >> t;
      door[s - 1][t - 1] = 1;
      door[t - 1][s - 1] = 1;
    }

    int lightstatus = 0;
    for (int i = 0; i < n; i++) {
      int tmp;
      cin >> tmp;
      lightstatus |= tmp << i;
    }
    for (int i = 0; i < n; i++) {
      int k;
      cin >> k;
      for (int j = 0; j < k; j++) {
        int tmp;
        cin >> tmp;
        switches[i] |= 1 << (tmp - 1);
      }
    }

    // tab[lightstatus][0] = 0;
    search(lightstatus, 0);

    if (tab[1 << (n - 1)][n - 1] < INF) {
      vector<pair<int, int>> path;
      pair<int, int> tmp(1 << (n - 1), n - 1);
      while (tmp != pair<int, int>(lightstatus, 0)) {
        path.push_back(tmp);
        tmp = from[tmp.first][tmp.second];
        if (tmp == pair<int, int>(-1, -1))
          abort();
      }
      path.push_back(tmp);
      reverse(path.begin(), path.end());

      cout << "You can go home in " << tab[1 << (n - 1)][n - 1] << " steps."
           << endl;
      ;

      vector<step> ans;
      for (int i = 1; i < path.size(); i++) {
        if (path[i - 1].second != path[i].second)
          ans.push_back(step(step::MOVE, path[i].second));
        else {
          int r;
          for (int j = 0; j < n; j++) {
            if ((path[i - 1].first ^ path[i].first) & (1 << j))
              r = j;
          }
          if (path[i].first & (1 << r)) {
            ans.push_back(step(step::SWITCH | step::ON, r));
          } else {
            ans.push_back(step(step::SWITCH, r));
          }
        }
      }
      for (int i = 0; i < ans.size(); i++) {
        if (ans[i].step_type == step::MOVE)
          cout << "Move to room " << ans[i].R + 1 << "." << endl;
        else {
          vector<step> v;
          for (; i < ans.size() && (ans[i].step_type & step::SWITCH); i++)
            v.push_back(ans[i]);
          sort(v.begin(), v.end());
          for (int j = 0; j < v.size(); j++) {
            if (v[j].step_type & step::ON)
              cout << "Switch on room " << v[j].R + 1 << "." << endl;
            else
              cout << "Switch off room " << v[j].R + 1 << "." << endl;
          }
          i--;
        }
      }
    } else {
      bool flg = false;
      for (int i = 0; i < (1 << n); i++) {
        if ((i & (1 << (n - 1))) && tab[i][n - 1] < INF) {
          flg = true;
          break;
        }
      }
      if (flg)
        cout << "You can not switch off all lights." << endl;
      else
        cout << "Help me!" << endl;
    }
  }
}