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

#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

struct NODE {
  int pos, bit;
  NODE(int a, int b) {
    pos = a;
    bit = b;
  }
  NODE() {}
};

NODE *done[1 << 15][15];
NODE Q[(1 << 15) * 15];
int n, m;

bool diff(int a, int b, vector<string> &ans) {
  int bit = a ^ b;
  bool f = false;
  rep(i, n) {
    if ((a >> i & 1) ^ (b >> i & 1)) {
      f = true;
      stringstream ss;
      ss << "Switch " << (a >> i & 1 ? "on" : "off") << " room " << i + 1
         << ".";
      ans.push_back(ss.str());
    }
  }
  return f;
}

int main() {
  while (cin >> n >> m && n) {
    vector<vector<int>> v(n);
    vector<vector<int>> room(n);
    rep(i, m) {
      int a, b;
      cin >> a >> b;
      a--, b--;
      v[a].push_back(b);
      v[b].push_back(a);
    }
    rep(i, n) sort(v[i].begin(), v[i].end());
    int init = 0;
    rep(i, n) {
      int a;
      cin >> a;
      init |= (a << i);
    }
    rep(i, n) {
      int c;
      cin >> c;
      rep(j, c) {
        int a;
        cin >> a;
        a--;
        if (a != i)
          room[i].push_back(1 << a);
      }
      sort(room[i].begin(), room[i].end());
    }
    rep(i, 1 << n) rep(j, n) done[i][j] = NULL;
    int head = 0, size = 0, ansbit = (1 << 30);
    bool flag = false;
    Q[size++] = NODE(0, init);
    done[init][0] = &Q[head];
    while (head < size) {
      NODE q = Q[head];
      if (q.pos == n - 1) {
        if (q.bit == (1 << (n - 1))) {
          vector<string> a;
          NODE r = q;
          while (1) {
            NODE next = (*done[r.bit][r.pos]);
            if (next.pos == r.pos && next.bit == r.bit)
              break;
            if (r.pos != next.pos) {
              stringstream ss;
              ss << "Move to room " << r.pos + 1 << ".";
              a.push_back(ss.str());
            } else {
              diff(r.bit, next.bit, a);
            }
            r = next;
          }
          cout << "You can go home in " << a.size() << " steps." << endl;
          rep(i, a.size()) { cout << a[a.size() - 1 - i] << endl; }
          goto exit;
        }
        flag = true;
      }
      rep(j, room[q.pos].size()) {
        int nextbit = q.bit ^ room[q.pos][j];
        if (done[nextbit][q.pos] == NULL) {
          done[nextbit][q.pos] = &Q[head];
          Q[size++] = NODE(q.pos, nextbit);
        }
      }
      rep(i, v[q.pos].size()) {
        if (q.bit >> v[q.pos][i] & 1) {
          if (done[q.bit][v[q.pos][i]] == NULL) {
            done[q.bit][v[q.pos][i]] = &Q[head];
            Q[size++] = NODE(v[q.pos][i], q.bit);
          }
        }
      }
      head++;
    }
    if (flag)
      cout << "You can not switch off all lights." << endl;
    else
      cout << "Help me!" << endl;
  exit:;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

struct NODE {
  int pos, cur;
  vector<char> type, num;
  NODE(int a, int b) { pos = a, cur = b; }
};
bool operator<(const NODE &a, const NODE &b) {
  return a.type.size() > b.type.size();
}
int n, m;

void output(vector<char> a, vector<char> b) {
  cout << "You can go home in " << a.size() << " steps." << endl;
  rep(i, a.size()) {
    if (a[i] == 0)
      cout << "Switch on room " << b[i] + 1 << ".";
    if (a[i] == 1)
      cout << "Switch off room " << b[i] + 1 << ".";
    if (a[i] == 2)
      cout << "Move to room " << b[i] + 1 << ".";
    cout << endl;
  }
}
int main() {
  while (cin >> n >> m, n || m) {
    int path[15][15] = {0};
    vector<int> light[15];
    int lBit[15] = {0};
    int state = 0;
    rep(i, m) {
      int a, b;
      cin >> a >> b;
      a--, b--;
      path[a][b] = path[b][a] = true;
    }
    rep(i, n) {
      int tmp;
      cin >> tmp;
      state |= tmp << i;
    }
    rep(i, n) {
      int k;
      cin >> k;
      rep(j, k) {
        int a;
        cin >> a;
        light[i].push_back(a - 1);
        lBit[i] |= 1 << (a - 1);
      }
    }
    bool memo[15][1 << 15] = {0};
    priority_queue<NODE> Q;
    Q.push(NODE(0, state));
    bool f = 0;
    while (Q.size()) {
      NODE q = Q.top();
      Q.pop();
      if (q.pos == n - 1 && (q.cur & lBit[n - 1]) == q.cur - (1 << (n - 1))) {
        int bit = q.cur - (1 << (n - 1));
        rep(i, n) if (bit >> i & 1) q.type.push_back(1), q.num.push_back(i);
        output(q.type, q.num);
        goto end;
      }
      if (q.pos == n - 1)
        f = true;

      if (memo[q.pos][q.cur])
        continue;
      else
        memo[q.pos][q.cur] = true;
      rep(x, n) {
        if (path[q.pos][x]) {
          rep(i, (1 << light[q.pos].size())) {
            NODE s = q;
            rep(j, light[q.pos].size()) {
              if (i >> j & 1) {
                s.type.push_back(q.cur >> light[q.pos][j] & 1);
                s.cur ^= (1 << light[q.pos][j]);
                s.num.push_back(light[q.pos][j]);
              }
            }
            s.type.push_back(2), s.num.push_back(x);
            s.pos = x;
            if (s.cur >> x & 1)
              Q.push(s);
          }
        }
      }
    }
    if (f)
      cout << "You can not switch off all lights." << endl;
    else
      cout << "Help me!" << endl;
  end:;
  }
}