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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;

typedef vector<string> VS;
typedef pair<int, int> Position;
typedef map<Position, int> Index;

const int size = 21;
int w, h;
bool O[size][size];
bool V[size][size][1 << 10];
Position D[size];
int DC;
Index ID;
int goal;

void init() {
  goal = 0;
  ID.clear();
  DC = 0;
  for (int i = 0; i < size; i++) {
    for (int j = 0; j < size; j++) {
      O[i][j] = false;
      for (int k = 0; k < 1 << 10; k++) {
        V[i][j][k] = false;
      }
    }
  }
}

typedef pair<int, int> PII;
typedef pair<PII, PII> Node;
typedef priority_queue<Node, vector<Node>, greater<Node>> Queue;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};

int solve(int sr, int sc) {
  Queue Q;
  Node start(PII(0, 0), PII(sr, sc));
  Q.push(start);
  V[sr][sc][0] = true;

  while (!Q.empty()) {
    Node node = Q.top();
    Q.pop();

    int cost = node.first.first;
    int dirt = node.first.second;
    Position pos = node.second;

    if (dirt == (1 << goal) - 1) {
      return cost;
    }

    for (int i = 0; i < 4; i++) {
      int nCost = cost + 1;
      Position nPos = pos;
      nPos.first += dr[i];
      nPos.second += dc[i];

      if (nPos.first < 0 || nPos.first >= h || nPos.second < 0 ||
          nPos.second >= w) {
        continue;
      }
      if (O[nPos.first][nPos.second]) {
        continue;
      }

      int nDirt = dirt;
      if (ID.find(nPos) != ID.end()) {
        int id = ID[nPos];
        if ((nDirt & (1 << id)) == 0) {
          nDirt = nDirt | (1 << id);
        }
      }

      if (V[nPos.first][nPos.second][nDirt]) {
        continue;
      }
      V[nPos.first][nPos.second][nDirt] = true;

      Node nNode(PII(nCost, nDirt), nPos);
      Q.push(nNode);
    }
  }

  return -1;
}

int main() {
  while (cin >> w >> h) {
    if (w == 0 && h == 0)
      break;
    init();

    VS lines(h);
    for (int i = 0; i < h; i++) {
      cin >> lines[i];
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == 'x') {
          O[i][j] = true;
        }
      }
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == '*') {
          ID[Position(i, j)] = DC;
          D[DC++] = Position(i, j);
          goal++;
        }
      }
    }
    int sr, sc;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == 'o') {
          sr = i;
          sc = j;
        }
      }
    }

    cout << solve(sr, sc) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;

typedef vector<string> VS;
typedef pair<int, int> Position;
typedef set<Position> Positions;

const int size = 21;
int w, h;
bool O[size][size];

void init() {
  for (int i = 0; i < size; i++) {
    for (int j = 0; j < size; j++) {
      O[i][j] = false;
    }
  }
}

typedef pair<Positions, Position> PPP;
typedef pair<int, PPP> Node;
typedef priority_queue<Node, vector<Node>, greater<Node>> Queue;
typedef map<PPP, int> MPI;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};

int solve(Positions initDC, int sr, int sc) {
  Queue Q;
  Node start(0, PPP(initDC, Position(sr, sc)));
  Q.push(start);
  MPI M;
  M[PPP(initDC, Position(sr, sc))] = 0;

  while (!Q.empty()) {
    Node node = Q.top();
    Q.pop();

    int cost = node.first;
    Positions DC = node.second.first;
    int r = node.second.second.first;
    int c = node.second.second.second;

    if (DC.size() == 0) {
      return cost;
    }

    for (int i = 0; i < 4; i++) {
      int nextCost = cost + 1;
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (nr < 0 || nr >= h || nc < 0 || nc >= w) {
        continue;
      }
      if (O[nr][nc]) {
        continue;
      }
      Position nPos(nr, nc);
      Positions nextDC = DC;
      if (nextDC.count(nPos)) {
        nextDC.erase(nPos);
      }
      PPP nodeSecond(nextDC, nPos);
      if (M.find(nodeSecond) == M.end()) {
        M[nodeSecond] = nextCost;
      } else if (nextCost >= M[nodeSecond]) {
        continue;
      }
      M[nodeSecond] = nextCost;
      Node nextNode(nextCost, nodeSecond);
      Q.push(nextNode);
    }
  }

  return -1;
}

int main() {
  while (cin >> w >> h) {
    if (w == 0 && h == 0)
      break;
    init();

    VS lines(h);
    for (int i = 0; i < h; i++) {
      cin >> lines[i];
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == 'x') {
          O[i][j] = true;
        }
      }
    }
    Positions DC;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == '*') {
          DC.insert(Position(i, j));
        }
      }
    }
    int sr, sc;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (lines[i][j] == 'o') {
          sr = i;
          sc = j;
        }
      }
    }

    cout << solve(DC, sr, sc) << endl;
  }
  return 0;
}