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

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#define MAX 15
#define YOU_CAN_NOT_SWITCH_OFF -2
#define NO_EXIT -1

#define MOVE 1
#define SWITCH_OFF 2
#define SWITCH_ON 3

const int inf = 1 << 22;

bool vis[MAX][1 << MAX];
bool adj[MAX][MAX];
int ans[MAX][1 << MAX];
int light[MAX][MAX];
int light_num[MAX];

struct State {
  State() : now(0), step(0), light(0) {}
  State(int n, int s, int l) : now(n), step(s), light(l) {}
  int light;
  int now;
  int step;
  vector<pair<int, int>> path;
  bool operator>(const State &t) const { return step > t.step; }
};

void ResetGraph() {
  for (int i = 0; i < MAX; ++i) {
    for (int j = 0; j < (1 << MAX); ++j) {
      vis[i][j] = false;
      ans[i][j] = inf;
    }
    for (int j = 0; j < MAX; ++j) {
      adj[i][j] = false;
      light[i][j] = 0;
    }
    light_num[i] = 0;
  }
}

State bfs(int n, int initial_light) {
  bool reachable = false;
  priority_queue<State, vector<State>, greater<State>> qs;
  State init(0, 0, initial_light);

  qs.push(init);
  while (!qs.empty()) {
    State ns = qs.top();
    qs.pop();

    if (ns.step >= ans[ns.now][ns.light] || vis[ns.now][ns.light])
      continue;
    ans[ns.now][ns.light] = ns.step;
    vis[ns.now][ns.light] = true;

    if (ns.now == n - 1) {
      reachable = true;
    }
    if (ns.now == n - 1 && ns.light == 1 << (n - 1)) {
      return ns;
    } else {
      int num = 0;
      int cand[MAX];

      for (int i = 0; i < n; ++i) {
        if (adj[ns.now][i]) {
          cand[num++] = i;
        }
      }

      // switch light
      for (int i = 0; i < light_num[ns.now]; ++i) {
        State next(ns.now, ns.step, ns.light);
        int target = light[ns.now][i];
        next.light ^= (1 << target);
        next.step++;
        next.path = ns.path;
        if (next.light & (1 << target)) {
          next.path.push_back(make_pair(SWITCH_ON, target + 1));
        } else {
          next.path.push_back(make_pair(SWITCH_OFF, target + 1));
        }
        if (next.step < ans[ns.now][next.light] && !vis[ns.now][next.light] &&
            next.light & (1 << ns.now)) {
          qs.push(next);
        }
      }

      // move
      for (int i = 0; i < num; ++i) {
        State next(cand[i], ns.step, ns.light);
        next.step++;
        next.path = ns.path;
        next.path.push_back(make_pair(MOVE, cand[i] + 1));
        if (next.step < ans[cand[i]][next.light] && !vis[cand[i]][next.light] &&
            next.light & (1 << cand[i])) {
          qs.push(next);
        }
      }
    }
  }

  State impossible_state;
  impossible_state.step = NO_EXIT;
  if (reachable)
    impossible_state.step = YOU_CAN_NOT_SWITCH_OFF;
  return impossible_state;
}

bool lessswroom(const pair<int, int> &a, const pair<int, int> &b) {
  return a.second < b.second;
}

int main() {
  while (true) {
    ResetGraph();
    int n, m;
    int initial_state = 0;
    cin >> n >> m;
    if (n == 0 && m == 0)
      break;
    for (int i = 0; i < m; ++i) {
      int s, t;
      cin >> s >> t;
      --s;
      --t;
      adj[s][t] = adj[t][s] = true;
    }
    for (int i = 0; i < n; ++i) {
      int ii;
      cin >> ii;
      if (ii) {
        initial_state |= (1 << i);
      }
    }
    for (int i = 0; i < n; ++i) {
      int k;
      cin >> k;
      light_num[i] = k;
      for (int j = 0; j < k; ++j) {
        int r;
        cin >> r;
        --r;
        light[i][j] = r;
      }
    }
    State answer = bfs(n, initial_state);
    if (answer.step == NO_EXIT) {
      cout << "Help me!" << endl;
    } else if (answer.step == YOU_CAN_NOT_SWITCH_OFF) {
      cout << "You can not switch off all lights." << endl;
    } else {
      cout << "You can go home in " << answer.step << " steps." << endl;
      int st = -1;
      vector<pair<int, int>> vp;

      answer.path.push_back(make_pair(MOVE, -1));
      for (int i = 0; i < answer.path.size(); ++i) {
        if (answer.path[i].first == MOVE) {
          if (st < 0)
            continue;
          sort(vp.begin(), vp.end(), lessswroom);
          for (int j = st; j < i; ++j) {
            answer.path[j] = vp[j - st];
          }
          vp.clear();
          st = -1;
        } else {
          if (st < 0)
            st = i;
          vp.push_back(answer.path[i]);
        }
      }
      answer.path.pop_back();
      for (int i = 0; i < answer.path.size(); ++i) {
        switch (answer.path[i].first) {
        case MOVE:
          cout << "Move to room " << answer.path[i].second << "." << endl;
          break;
        case SWITCH_OFF:
          cout << "Switch off room " << answer.path[i].second << "." << endl;
          break;
        case SWITCH_ON:
          cout << "Switch on room " << answer.path[i].second << "." << endl;
          break;
        }
      }
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#define MAX 15
#define YOU_CAN_NOT_SWITCH_OFF -2
#define NO_EXIT -1

#define MOVE 1
#define SWITCH_OFF 2
#define SWITCH_ON 3

const int inf = 1 << 22;

bool vis[MAX][1 << MAX];
bool adj[MAX][MAX];
int ans[MAX][1 << MAX];
int light[MAX][MAX];
int light_num[MAX];

struct State {
  State() : now(0), step(0), light(0) {}
  State(int n, int s, int l) : now(n), step(s), light(l) {}
  int light;
  int now;
  int step;
  vector<pair<int, int>> path;
  bool operator>(const State &t) const { return step > t.step; }
};

void ResetGraph() {
  for (int i = 0; i < MAX; ++i) {
    for (int j = 0; j < (1 << MAX); ++j) {
      vis[i][j] = false;
      ans[i][j] = inf;
    }
    for (int j = 0; j < MAX; ++j) {
      adj[i][j] = false;
      light[i][j] = 0;
    }
    light_num[i] = 0;
  }
}

State bfs(int n, int initial_light) {
  bool reachable = false;
  priority_queue<State, vector<State>, greater<State>> qs;
  State init(0, 0, initial_light);

  qs.push(init);
  while (!qs.empty()) {
    State ns = qs.top();
    qs.pop();

    if (ns.step >= ans[ns.now][ns.light])
      continue;
    ans[ns.now][ns.light] = ns.step;
    vis[ns.now][ns.light] = true;

    if (ns.now == n - 1) {
      reachable = true;
    }
    if (ns.now == n - 1 && ns.light == 1 << (n - 1)) {
      return ns;
    } else {
      int num = 0;
      int cand[MAX];

      for (int i = 0; i < n; ++i) {
        if (adj[ns.now][i]) {
          cand[num++] = i;
        }
      }
      cand[num++] = ns.now;

      for (int i = 0; i < num; ++i) {
        for (int mask = 0; mask < (1 << light_num[ns.now]); ++mask) {
          State next(cand[i], ns.step, ns.light);
          ostringstream oss;
          // next.path = ns.path;

          for (int j = 0; j < light_num[ns.now]; ++j) {
            if (mask & (1 << j)) {
              int target = light[ns.now][j];

              next.light ^= (1 << target);
              next.step++;
              ostringstream toss;
              if (next.light & (1 << target)) {
                // next.path.push_back( make_pair( SWITCH_ON, target+1 ) );
              } else {
                // next.path.push_back( make_pair( SWITCH_OFF, target+1 ) );
              }
            }
          }

          if (cand[i] != ns.now) {
            next.step++;
            // next.path.push_back( make_pair( MOVE,cand[i]+1 ) );
          }

          if (next.step < ans[cand[i]][next.light] &&
              !vis[cand[i]][next.light] && next.light & (1 << cand[i])) {
            qs.push(next);
          }
        }
      }
    }
  }

  State impossible_state;
  impossible_state.step = NO_EXIT;
  if (reachable)
    impossible_state.step = YOU_CAN_NOT_SWITCH_OFF;
  return impossible_state;
}

int main() {
  while (true) {
    ResetGraph();
    int n, m;
    int initial_state = 0;
    cin >> n >> m;
    if (n == 0 && m == 0)
      break;
    for (int i = 0; i < m; ++i) {
      int s, t;
      cin >> s >> t;
      --s;
      --t;
      adj[s][t] = adj[t][s] = true;
    }
    for (int i = 0; i < n; ++i) {
      int ii;
      cin >> ii;
      if (ii) {
        initial_state |= (1 << i);
      }
    }
    for (int i = 0; i < n; ++i) {
      int k;
      cin >> k;
      light_num[i] = k;
      for (int j = 0; j < k; ++j) {
        int r;
        cin >> r;
        --r;
        light[i][j] = r;
      }
    }
    State answer = bfs(n, initial_state);
    if (answer.step == NO_EXIT) {
      cout << "Help me!" << endl;
    } else if (answer.step == YOU_CAN_NOT_SWITCH_OFF) {
      cout << "You can not switch off all lights." << endl;
    } else {
      cout << "You can go home in " << answer.step << " steps." << endl;
      /*
      for(int i = 0; i < answer.path.size(); ++i){
        switch( answer.path[i].first ){
        case MOVE:
          cout << "Move to room " << answer.path[i].second << "." << endl;
          break;
        case SWITCH_OFF:
          cout << "Switch off room " << answer.path[i].second << "." << endl;
          break;
        case SWITCH_ON:
          cout << "Switch on room " << answer.path[i].second << "." << endl;
          break;
        }
      }
      */
    }
  }
  return 0;
}