Problem p00643 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define F first
#define S second
using namespace std;
typedef pair<int, int> P;
int h, w, imap[20][20];
P s, g;
const int dx[4] = {0, 1, 0, -1}; // 0:下、1:右、2:上、3:左
const int dy[4] = {1, 0, -1, 0};
// bool used[20][20];
int dpused[20][20];
int candidate;
int dice[6] = {1, 2, 4, 5, 3, 6}; // 0:top,1:front,2:left,3:back,4:right,5:bottom

int Reverse(int p) {
  if (p == 0)
    return 2;
  if (p == 1)
    return 3;
  if (p == 2)
    return 0;
  if (p == 3)
    return 1;
}
/*
void RollMe(int face){ //enomoto
  if(face == 0){
    int h = dice[3];
    dice[3] = dice[5];
    dice[5] = dice[1];
    dice[1] = dice[0];
    dice[0] = h;
  }
  else if(face == 1){
    int h = dice[0];
    dice[0] = dice[2];
    dice[2] = dice[5];
    dice[5] = dice[4];
    dice[4] = h;
  }
  else if(face == 2){
    int h = dice[0];
    dice[0] = dice[1];
    dice[1] = dice[5];
    dice[5] = dice[3];
    dice[3] = h;
  }
  else if(face == 3){
    int h = dice[0];
    dice[0] = dice[4];
    dice[4] = dice[5];
    dice[5] = dice[2];
    dice[2] = h;
  }
}
*/
/*
void rec(P p,int sam){
  //cout << "Pos = " << p.F << " " << p.S << ",sam = " << sam << endl;
  if(p == g){
    candidate = min(candidate,sam);
    return;
  }
  for(int i=0;i<4;i++){
    int nx = p.F+dx[i],ny = p.S+dy[i];
*/
// if(/*!used[ny][nx] &&*/// !(0<=nx && nx<w && 0<=ny && ny <h))continue;
// cout << "nx = " << nx << " ny = "  << ny << endl;//
//      RollMe(i);
// if( dpused[ny][nx] > (sam+imap[ny][nx]*dice[5]) ){
// used[ny][nx] = true;//
// RollMe(i);//
// dpused[ny][nx] = sam+imap[ny][nx]*dice[5];
// rec(P(nx,ny),dice[5]*imap[ny][nx]+sam);
// RollMe(Reverse(i));//
// used[ny][nx] = false;//
//   }
//    RollMe(Reverse(i));
//}
//}

int idx(int tp, int ft) { return tp * 10 + ft; }

struct special {
  int x, y, top, front, left, back, right, bottom, cost;
  // special (int x,int y,int top,int front,int left,int back,int right,int
  // bottom,int
  // cost):x(x),y(y),top(top),front(front),left(left),back(back),right(right),bottom(bottom),cost(cost){}

  bool operator<(const special &p) const { return cost > p.cost; }

  // 0->top, 1->front, 2->left, 3->back, 4->right, 5->bottom
  void RollMe(int face) { // enomoto
    if (face == 0) {
      int h = back;
      back = bottom;
      bottom = front;
      front = top;
      top = h;
    } else if (face == 1) {
      int h = top;
      top = left;
      left = bottom;
      bottom = right;
      right = h;
    } else if (face == 2) {
      int h = top;
      top = front;
      front = bottom;
      bottom = back;
      back = h;
    } else if (face == 3) {
      int h = top;
      top = right;
      right = bottom;
      bottom = left;
      left = h;
    }
  }
};
int D[20][20][100];
const int INF = 1 << 30;
int main() {
  while (cin >> h >> w && h && w) {
    candidate = INF;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++)
        cin >> imap[i][j];
    }
    cin >> s.S >> s.F;
    cin >> g.S >> g.F;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) { // used[i][j] = false;
        //	dpused[i][j] = INF;
        for (int k = 0; k < 100; k++)
          D[i][j][k] = INF;
      }

    // used[s.S][s.F] = true;
    // dpused[s.S][s.F] = 0;
    // rec(s,0);
    D[s.S][s.F][idx(1, 2)] = 0;
    priority_queue<special> que;
    special In;
    // int dice[6] =
    // {1,2,4,5,3,6};//0:top,1:front,2:left,3:back,4:right,5:bottom
    In.x = s.F;
    In.y = s.S;
    In.top = 1;
    In.front = 2;
    In.left = 4;
    In.back = 5;
    In.right = 3;
    In.bottom = 6;
    In.cost = 0;
    que.push(In);
    // special - > x,y,top,front,left,back,right,bottom,cost;
    while (!que.empty()) {
      special pos = que.top();
      que.pop();
      // majesty
      if (pos.x == g.F && pos.y == g.S) {
        candidate = min(candidate, pos.cost);
        break;
      }

      for (int i = 0; i < 4; i++) {
        int nx = pos.x + dx[i], ny = pos.y + dy[i];

        if (!(0 <= nx && nx < w && 0 <= ny && ny < h))
          continue;
        pos.RollMe(i);

        if (D[ny][nx][idx(pos.top, pos.front)] >
            imap[ny][nx] * pos.bottom + pos.cost) {
          D[ny][nx][idx(pos.top, pos.front)] =
              imap[ny][nx] * pos.bottom + pos.cost;
          In.x = nx;
          In.y = ny;
          In.top = pos.top;
          In.front = pos.front;
          In.back = pos.back;
          In.left = pos.left;
          In.right = pos.right;
          In.bottom = pos.bottom;
          In.cost = imap[ny][nx] * pos.bottom + pos.cost;
          que.push(In);
        }
        pos.RollMe(Reverse(i));
      }
    }

    /*
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++)cout << dpused[i][j] << " ";
      cout << endl;
    }
    */
    assert(candidate != INF);
    cout << candidate << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#define F first
#define S second
using namespace std;
typedef pair<int, int> P;
int h, w, imap[20][20];
P s, g;
const int dx[4] = {0, 1, 0, -1}; // 0:下、1:右、2:上、3:左
const int dy[4] = {1, 0, -1, 0};
// bool used[20][20];
int dpused[20][20];
int candidate;
int dice[6] = {1, 2, 4, 5, 3, 6}; // 0:top,1:front,2:left,3:back,4:right,5:bottom

int Reverse(int p) {
  if (p == 0)
    return 2;
  if (p == 1)
    return 3;
  if (p == 2)
    return 0;
  if (p == 3)
    return 1;
}

void RollMe(int face) { // enomoto
  if (face == 0) {
    int h = dice[3];
    dice[3] = dice[5];
    dice[5] = dice[1];
    dice[1] = dice[0];
    dice[0] = h;
  } else if (face == 1) {
    int h = dice[0];
    dice[0] = dice[2];
    dice[2] = dice[5];
    dice[5] = dice[4];
    dice[4] = h;
  } else if (face == 2) {
    int h = dice[0];
    dice[0] = dice[1];
    dice[1] = dice[5];
    dice[5] = dice[3];
    dice[3] = h;
  } else if (face == 3) {
    int h = dice[0];
    dice[0] = dice[4];
    dice[4] = dice[5];
    dice[5] = dice[2];
    dice[2] = h;
  }
}

void rec(P p, int sam) {
  // cout << "Pos = " << p.F << " " << p.S << ",sam = " << sam << endl;
  if (p == g) {
    candidate = min(candidate, sam);
    return;
  }
  for (int i = 0; i < 4; i++) {
    int nx = p.F + dx[i], ny = p.S + dy[i];

    if (/*!used[ny][nx] &&*/ !(0 <= nx && nx < w && 0 <= ny && ny < h))
      continue;
    // cout << "nx = " << nx << " ny = "  << ny << endl;
    RollMe(i);
    if (dpused[ny][nx] >= (sam + imap[ny][nx] * dice[5])) {
      // used[ny][nx] = true;
      // RollMe(i);
      dpused[ny][nx] = sam + imap[ny][nx] * dice[5];
      rec(P(nx, ny), dice[5] * imap[ny][nx] + sam);
      // RollMe(Reverse(i));
      // used[ny][nx] = false;
    }
    RollMe(Reverse(i));
  }
}

const int INF = 1 << 30;
int main() {
  while (cin >> h >> w && h && w) {
    candidate = INF;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++)
        cin >> imap[i][j];
    }
    cin >> s.S >> s.F;
    cin >> g.S >> g.F;
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) { // used[i][j] = false;
        dpused[i][j] = INF;
      }
    // used[s.S][s.F] = true;
    dpused[s.S][s.F] = 0;
    rec(s, 0);
    assert(candidate != INF);
    cout << candidate << endl;
  }
  return 0;
}