Problem p00721 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ALL(g) (g).begin(), (g).end()
#define REP(i, x, n) for (int i = x; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define F(i, j, k) fill(i[0], i[0] + j * j, k)
#define P(p) cout << (p) << endl;
#define EXIST(s, e) ((s).find(e) != (s).end())
#define INF 1 << 25
#define pb push_back

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int, int> pii;
typedef pair<long, long> pll;
typedef long long ll;

using namespace std;

struct robot {
  int x, y, cost, dust;

  bool operator>(const robot &r) const { return cost > r.cost; }
};

int main() {
  int w, h;
  while (cin >> w >> h, w | h) {
    // input
    vector<string> v;
    rep(j, h) {
      string input;
      cin >> input;
      v.pb(input);
    }

    // dust map
    int dust[20][20];
    fill_n((int *)dust, 20 * 20, 0);
    int bit = 1;

    // start & goal
    int sx, sy;
    int goal = 0;
    rep(j, h) {
      rep(i, w) {
        if (v[j][i] == 'o') {
          sx = i;
          sy = j;
        }
        if (v[j][i] == '*') {
          dust[j][i] = bit;
          goal += bit;
          bit *= 2;
        }
      }
    }

    // bfs
    int check[20][20][1 << 10];
    fill_n((int *)check, 20 * 20 * (1 << 10), INT_MAX);
    int cost = -1;
    priority_queue<robot, vector<robot>, greater<robot>> q;
    q.push((robot){sx, sy, 0, 0});
    while (!q.empty()) {
      robot p = q.top();
      q.pop();
      // goal
      if (p.dust == goal) {
        cost = p.cost;
        break;
      }
      // up
      if (p.y - 1 >= 0 && v[p.y - 1][p.x] != 'x') {
        if (v[p.y - 1][p.x] == '*' &&
            (p.dust & dust[p.y - 1][p.x]) != dust[p.y - 1][p.x]) {
          if (check[p.y - 1][p.x][p.dust + dust[p.y - 1][p.x]] > p.cost + 1) {
            q.push(
                (robot){p.x, p.y - 1, p.cost + 1, p.dust + dust[p.y - 1][p.x]});
            check[p.y - 1][p.x][p.dust + dust[p.y - 1][p.x]] = p.cost + 1;
          }
        } else {
          if (check[p.y - 1][p.x][p.dust] > p.cost + 1) {
            q.push((robot){p.x, p.y - 1, p.cost + 1, p.dust});
            check[p.y - 1][p.x][p.dust] = p.cost + 1;
          }
        }
      }
      // down
      if (p.y + 1 < h && v[p.y + 1][p.x] != 'x') {
        if (v[p.y + 1][p.x] == '*' &&
            (p.dust & dust[p.y + 1][p.x]) != dust[p.y + 1][p.x]) {
          if (check[p.y + 1][p.x][p.dust + dust[p.y + 1][p.x]] > p.cost + 1) {
            q.push(
                (robot){p.x, p.y + 1, p.cost + 1, p.dust + dust[p.y + 1][p.x]});
            check[p.y + 1][p.x][p.dust + dust[p.y + 1][p.x]] = p.cost + 1;
          }
        } else {
          if (check[p.y + 1][p.x][p.dust] > p.cost + 1) {
            q.push((robot){p.x, p.y + 1, p.cost + 1, p.dust});
            check[p.y + 1][p.x][p.dust] = p.cost + 1;
          }
        }
      }
      // right
      if (p.x + 1 < w && v[p.y][p.x + 1] != 'x') {
        if (v[p.y][p.x + 1] == '*' &&
            (p.dust & dust[p.y][p.x + 1]) != dust[p.y][p.x + 1]) {
          if (check[p.y][p.x + 1][p.dust + dust[p.y][p.x + 1]] > p.cost + 1) {
            q.push(
                (robot){p.x + 1, p.y, p.cost + 1, p.dust + dust[p.y][p.x + 1]});
            check[p.y][p.x + 1][p.dust + dust[p.y][p.x + 1]] = p.cost + 1;
          }
        } else {
          if (check[p.y][p.x + 1][p.dust] > p.cost + 1) {
            q.push((robot){p.x + 1, p.y, p.cost + 1, p.dust});
            check[p.y][p.x + 1][p.dust] = p.cost + 1;
          }
        }
      }
      // left
      if (p.x - 1 >= 0 && v[p.y][p.x - 1] != 'x') {
        if (v[p.y][p.x - 1] == '*' &&
            (p.dust & dust[p.y][p.x - 1]) != dust[p.y][p.x - 1]) {
          if (check[p.y][p.x - 1][p.dust + dust[p.y][p.x - 1]] > p.cost + 1) {
            q.push(
                (robot){p.x - 1, p.y, p.cost + 1, p.dust + dust[p.y][p.x - 1]});
            check[p.y][p.x - 1][p.dust + dust[p.y][p.x - 11]] = p.cost + 1;
          }
        } else {
          if (check[p.y][p.x - 1][p.dust] > p.cost + 1) {
            q.push((robot){p.x - 1, p.y, p.cost + 1, p.dust});
            check[p.y][p.x - 1][p.dust] = p.cost + 1;
          }
        }
      }
    }
    cout << cost << endl;
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ALL(g) (g).begin(), (g).end()
#define REP(i, x, n) for (int i = x; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define F(i, j, k) fill(i[0], i[0] + j * j, k)
#define P(p) cout << (p) << endl;
#define EXIST(s, e) ((s).find(e) != (s).end())
#define INF 1 << 25
#define pb push_back

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int, int> pii;
typedef pair<long, long> pll;
typedef long long ll;

using namespace std;

struct robot {
  int x, y, cost, dust;

  bool operator>(const robot &r) const { return cost > r.cost; }
};

int main() {
  int w, h;
  while (cin >> w >> h, w | h) {
    // input
    vector<string> v;
    rep(j, h) {
      string input;
      cin >> input;
      v.pb(input);
    }

    // dust map
    int dust[20][20];
    fill_n((int *)dust, 20 * 20, 0);
    int bit = 1;

    // start & goal
    int sx, sy;
    int goal = 0;
    rep(j, h) {
      rep(i, w) {
        if (v[j][i] == 'o') {
          sx = i;
          sy = j;
        }
        if (v[j][i] == '*') {
          dust[j][i] = bit;
          goal += bit;
          bit *= 2;
        }
      }
    }

    // bfs
    int check[20][20][1 << 10];
    fill_n((int *)check, 20 * 20 * (1 << 10), INT_MAX);
    int cost = -1;
    priority_queue<robot, vector<robot>, greater<robot>> q;
    q.push((robot){sx, sy, 0, 0});
    while (!q.empty()) {
      robot p = q.top();
      q.pop();
      // goal
      if (p.dust == goal) {
        cost = p.cost;
        break;
      }
      // up
      if (p.y - 1 >= 0 && v[p.y - 1][p.x] != 'x') {
        if (v[p.y - 1][p.x] == '*' &&
            (p.dust & dust[p.y - 1][p.x]) != dust[p.y - 1][p.x]) {
          if (check[p.y - 1][p.x][p.dust + dust[p.y - 1][p.x]] > p.cost + 1) {
            q.push(
                (robot){p.x, p.y - 1, p.cost + 1, p.dust + dust[p.y - 1][p.x]});
            check[p.y - 1][p.x][p.dust + dust[p.y - 1][p.x]] = p.cost + 1;
          }
        } else {
          if (check[p.y - 1][p.x][p.dust] > p.cost + 1) {
            q.push((robot){p.x, p.y - 1, p.cost + 1, p.dust});
            check[p.y - 1][p.x][p.dust] = p.cost + 1;
          }
        }
      }
      // down
      if (p.y + 1 < h && v[p.y + 1][p.x] != 'x') {
        if (v[p.y + 1][p.x] == '*' &&
            (p.dust & dust[p.y + 1][p.x]) != dust[p.y + 1][p.x]) {
          if (check[p.y + 1][p.x][p.dust + dust[p.y + 1][p.x]] > p.cost + 1) {
            q.push(
                (robot){p.x, p.y + 1, p.cost + 1, p.dust + dust[p.y + 1][p.x]});
            check[p.y + 1][p.x][p.dust + dust[p.y + 1][p.x]] = p.cost + 1;
          }
        } else {
          if (check[p.y + 1][p.x][p.dust] > p.cost + 1) {
            q.push((robot){p.x, p.y + 1, p.cost + 1, p.dust});
            check[p.y + 1][p.x][p.dust] = p.cost + 1;
          }
        }
      }
      // right
      if (p.x + 1 < w && v[p.y][p.x + 1] != 'x') {
        if (v[p.y][p.x + 1] == '*' &&
            (p.dust & dust[p.y][p.x + 1]) != dust[p.y][p.x + 1]) {
          if (check[p.y][p.x + 1][p.dust + dust[p.y][p.x + 1]] > p.cost + 1) {
            q.push(
                (robot){p.x + 1, p.y, p.cost + 1, p.dust + dust[p.y][p.x + 1]});
            check[p.y][p.x + 1][p.dust + dust[p.y][p.x + 1]] = p.cost + 1;
          }
        } else {
          if (check[p.y][p.x + 1][p.dust] > p.cost + 1) {
            q.push((robot){p.x + 1, p.y, p.cost + 1, p.dust});
            check[p.y][p.x + 1][p.dust] = p.cost + 1;
          }
        }
      }
      // left
      if (p.x - 1 >= 0 && v[p.y][p.x - 1] != 'x') {
        if (v[p.y][p.x - 1] == '*' &&
            (p.dust & dust[p.y][p.x - 1]) != dust[p.y][p.x - 1]) {
          if (check[p.y][p.x - 1][p.dust + dust[p.y][p.x - 1]] > p.cost + 1) {
            q.push(
                (robot){p.x - 1, p.y, p.cost + 1, p.dust + dust[p.y][p.x - 1]});
            check[p.y][p.x - 1][p.dust + dust[p.y][p.x - 1]] = p.cost + 1;
          }
        } else {
          if (check[p.y][p.x - 1][p.dust] > p.cost + 1) {
            q.push((robot){p.x - 1, p.y, p.cost + 1, p.dust});
            check[p.y][p.x - 1][p.dust] = p.cost + 1;
          }
        }
      }
    }
    cout << cost << endl;
  }

  return 0;
}