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

#include <bits/stdc++.h>
using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define INF (1 << 29)

typedef pair<int, int> pii;

int n, m;
int startBit;
int dp[1 << 16][15];
int prevBit[1 << 16][15];
int prevPos[1 << 16][15];
vector<int> graph[15];
vector<int> swit[15];

int main() {
  while (cin >> n >> m, n || m) {
    startBit = 0;
    fill(dp[0], dp[1 << 16], INF);
    fill(prevBit[0], prevBit[1 << 16], INF);
    fill(prevPos[0], prevBit[1 << 16], INF);
    REP(i, n) graph[i].clear();
    REP(i, n) swit[i].clear();

    REP(i, m) {
      int a, b;
      scanf("%d %d", &a, &b);
      a--;
      b--;
      graph[a].push_back(b);
      graph[b].push_back(a);
    }
    REP(i, n) {
      int a;
      scanf("%d", &a);
      startBit |= (a << i);
    }
    REP(i, n) {
      int c;
      scanf("%d", &c);
      REP(j, c) {
        int a;
        scanf("%d", &a);
        a--;
        swit[i].push_back(a);
      }
    }

    queue<pii> que;
    que.push(pii(startBit, 0));
    dp[startBit][0] = 0;

    while (!que.empty()) {
      int nowBit = que.front().first;
      int nowPos = que.front().second;
      que.pop();

      if ((nowBit & (1 << nowPos) == 0))
        continue;

      REP(i, graph[nowPos].size()) {
        int nextPos = graph[nowPos][i];

        if ((nowBit & (1 << nextPos)) > 0 &&
            dp[nowBit][nextPos] > dp[nowBit][nowPos] + 1) {

          prevBit[nowBit][nextPos] = nowBit;
          prevPos[nowBit][nextPos] = nowPos;
          dp[nowBit][nextPos] = dp[nowBit][nowPos] + 1;
          que.push(pii(nowBit, nextPos));
        }
      }

      REP(i, swit[nowPos].size()) {
        int nextBit = nowBit ^ (1 << swit[nowPos][i]);

        if (swit[nowPos][i] == nowPos)
          continue;
        if (dp[nextBit][nowPos] > dp[nowBit][nowPos] + 1) {
          prevBit[nextBit][nowPos] = nowBit;
          prevPos[nextBit][nowPos] = nowPos;
          dp[nextBit][nowPos] = dp[nowBit][nowPos] + 1;
          que.push(pii(nextBit, nowPos));
        }
      }
    }

    if (dp[1 << (n - 1)][n - 1] != INF) {
      printf("You can go home in %d steps.\\n", dp[1 << (n - 1)][n - 1]);
      vector<pii> ans; // first: 1move 2switch on 3switch off	second: number

      int nowBit = 1 << (n - 1);
      int nowPos = n - 1;

      while (dp[nowBit][nowPos] != 0) {
        int nextBit = prevBit[nowBit][nowPos];
        int nextPos = prevPos[nowBit][nowPos];

        if (nextBit == nowBit)
          ans.push_back(pii(1, nowPos + 1));
        else {
          int tmp, pat;
          if (nextBit > nowBit) {
            pat = 3;
            tmp = nextBit & ~nowBit;
          } else {
            pat = 2;
            tmp = nowBit & ~nextBit;
          }

          int c = 0;
          while (tmp > 0) {
            tmp >>= 1;
            c++;
          }
          ans.push_back(pii(pat, c));
        }

        nowBit = nextBit;
        nowPos = nextPos;
      }
      reverse(ans.begin(), ans.end());
      REP(i, ans.size()) {
        if (ans[i].first == 1) {
          printf("Move to room %d.\\n", ans[i].second);
        } else {
          vector<pii> tmp;
          while (i < ans.size() && ans[i].first != 1) {
            tmp.push_back(pii(ans[i].second, ans[i].first));
            i++;
          }
          i--;
          sort(tmp.begin(), tmp.end());
          REP(j, tmp.size()) {
            if (tmp[j].second == 2)
              printf("Switch on room %d.\\n", tmp[j].first);
            else
              printf("Switch off room %d.\\n", tmp[j].first);
          }
        }
      }
    } else {
      bool flag = false;
      REP(i, 1 << n) if (dp[i][n - 1] != INF) flag = true;
      if (flag)
        puts("You can not switch off all lights.");
      else
        puts("Help me!");
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define INF (1 << 29)

typedef pair<int, int> pii;

int n, m;
int startBit;
int dp[1 << 16][15];
int prevBit[1 << 16][15];
int prevPos[1 << 16][15];
vector<int> graph[15];
vector<int> swit[15];

int main() {
  while (cin >> n >> m, n || m) {
    startBit = 0;
    fill(dp[0], dp[1 << 16], INF);
    fill(prevBit[0], prevBit[1 << 16], INF);
    fill(prevPos[0], prevBit[1 << 16], INF);
    REP(i, 15) graph[i].clear();
    REP(i, 15) swit[i].clear();

    REP(i, m) {
      int a, b;
      scanf("%d %d", &a, &b);
      a--;
      b--;
      graph[a].push_back(b);
      graph[b].push_back(a);
    }
    REP(i, n) {
      int a;
      scanf("%d", &a);
      startBit |= (a << i);
    }
    REP(i, n) {
      int c;
      scanf("%d", &c);
      REP(j, c) {
        int a;
        scanf("%d", &a);
        a--;
        swit[i].push_back(a);
      }
    }

    priority_queue<pair<int, pii>, vector<pair<int, pii>>,
                   greater<pair<int, pii>>>
        pq;
    pq.push(make_pair(0, pii(startBit, 0)));

    while (!pq.empty()) {
      int step = pq.top().first;
      int nowBit = pq.top().second.first;
      int nowPos = pq.top().second.second;
      pq.pop();

      if (dp[nowBit][nowPos] < step)
        continue;
      dp[nowBit][nowPos] = step;

      REP(i, graph[nowPos].size()) {
        int nextPos = graph[nowPos][i];

        if ((nowBit & (1 << nextPos)) > 0 && dp[nowBit][nextPos] > step + 1) {

          prevBit[nowBit][nextPos] = nowBit;
          prevPos[nowBit][nextPos] = nowPos;
          pq.push(make_pair(step + 1, pii(nowBit, nextPos)));
        }
      }

      REP(i, swit[nowPos].size()) {
        int nextBit = nowBit ^ (1 << swit[nowPos][i]);

        if (dp[nextBit][nowPos] > step + 1) {
          prevBit[nextBit][nowPos] = nowBit;
          prevPos[nextBit][nowPos] = nowPos;
          pq.push(make_pair(step + 1, pii(nextBit, nowPos)));
        }
      }
    }

    if (dp[1 << (n - 1)][n - 1] != INF) {
      printf("You can go home in %d steps.\\n", dp[1 << (n - 1)][n - 1]);
      vector<pii> ans; // first: 1move 2switch on 3switch off	second: number

      int nowBit = 1 << (n - 1);
      int nowPos = n - 1;

      while (dp[nowBit][nowPos] != 0) {
        int nextBit = prevBit[nowBit][nowPos];
        int nextPos = prevPos[nowBit][nowPos];

        if (nextBit == nowBit)
          ans.push_back(pii(1, nowPos + 1));
        else {
          int tmp, pat;
          if (nextBit > nowBit) {
            pat = 3;
            tmp = nextBit & ~nowBit;
          } else {
            pat = 2;
            tmp = nowBit & ~nextBit;
          }

          int c = 0;
          while (tmp > 0) {
            tmp >>= 1;
            c++;
          }
          ans.push_back(pii(pat, c));
        }

        nowBit = nextBit;
        nowPos = nextPos;
      }
      reverse(ans.begin(), ans.end());
      REP(i, ans.size()) {
        if (ans[i].first == 1) {
          printf("Move to room %d.\\n", ans[i].second);
        } else {
          vector<pii> tmp;
          while (i < ans.size() && ans[i].first != 1) {
            tmp.push_back(pii(ans[i].second, ans[i].first));
            i++;
          }
          i--;
          sort(tmp.begin(), tmp.end());
          REP(j, tmp.size()) {
            if (tmp[j].second == 2)
              printf("Switch on room %d.\\n", tmp[j].first);
            else
              printf("Switch off room %d.\\n", tmp[j].first);
          }
        }
      }
    } else {
      bool flag = false;
      REP(i, 1 << (n - 1))
      if (dp[i | (1 << (n - 1))][n - 1] != INF) flag = true;
      if (flag)
        puts("You can not switch off all lights.");
      else
        puts("Help me!");
    }
  }
  return 0;
}