Problem p00234 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct S {
  int x, y, o, s, t;
  S(int x, int y, int o, int s, int t) : x(x), y(y), o(o), s(s), t(t) {}
  bool operator<(const S &st) const {
    if (t != st.t)
      return t > st.t; // reverse
    if (x != st.x)
      return x < st.x;
    if (y != st.y)
      return y < st.y;
    if (o != st.o)
      return o < st.o;
    return s < st.s;
  }
};

int W, H;
int F, M, O;
int A[10][10];

bool update(S s, int dist[10][10][51][1 << 10]) {
  assert(valid(s.x, s.y, W, H));
  assert(s.o >= 0 && s.o <= 50);
  assert(s.s >= 0 && s.s < (1 << W));
  int &d = dist[s.y][s.x][s.o][s.s];
  if (d > s.t) {
    d = s.t;
    return true;
  } else {
    return false;
  }
}
void move(S &s, int dx) {
  s.x += dx;
  s.o--;
  if (dx == 0) {
    s.s = 0;
    s.y++;
  }
  if (!(s.s >> s.x & 1)) {
    s.s |= 1 << s.x;
    assert(valid(s.x, s.y, W, H));
    if (A[s.y][s.x] < 0) {
      s.t += abs(A[s.y][s.x]);
    } else {
      s.o = min(s.o + abs(A[s.y][s.x]), M);
    }
  }
}
void print(S s) {
  printf("x = %d y = %d o = %d s = %04X t = %d\n", s.x, s.y, s.o, s.s, s.t);
}

int main() {
  while (cin >> W >> H && W) {
    cin >> F >> M >> O;
    REP(y, H) REP(x, W) cin >> A[y][x];
    static int dist[10][10][51][1 << 10];
    REP(y, H) REP(x, W) REP(o, M + 1) REP(s, 1 << W) dist[y][x][o][s] = INF;
    priority_queue<S> que;
    REP(sx, W) {
      S start(sx, -1, O, 0, 0);
      move(start, 0);
      update(start, dist);
      que.push(start);
    }
    int ans = -1;
    while (!que.empty()) {
      S s = que.top();
      que.pop();
      // print(s);
      if (s.y == H - 1) {
        ans = s.t;
        break;
      }
      if (dist[s.y][s.x][s.o][s.s] < s.t)
        continue;
      if (s.o <= 1)
        continue;
      for (int dx = -1; dx <= 1; dx++) {
        if (!(s.x + dx >= 0 && s.x + dx < W))
          continue;
        S next = s;
        move(next, dx);
        if (update(next, dist)) {
          que.push(next);
        }
      }
    }
    if (ans == -1 || ans > F)
      cout << "NA" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct S {
  int x, y, o, s, t;
  S(int x, int y, int o, int s, int t) : x(x), y(y), o(o), s(s), t(t) {}
  bool operator<(const S &st) const {
    if (t != st.t)
      return t > st.t; // reverse
    if (x != st.x)
      return x < st.x;
    if (y != st.y)
      return y < st.y;
    if (o != st.o)
      return o < st.o;
    return s < st.s;
  }
};

int W, H;
int F, M, O;
int A[10][10];

bool update(S s, int dist[10][10][51][1 << 10]) {
  assert(valid(s.x, s.y, W, H));
  assert(s.o >= 0 && s.o <= 50);
  assert(s.s >= 0 && s.s < (1 << W));
  int &d = dist[s.y][s.x][s.o][s.s];
  if (d > s.t) {
    d = s.t;
    return true;
  } else {
    return false;
  }
}
void move(S &s, int dx) {
  s.x += dx;
  s.o--;
  if (dx == 0) {
    s.s = 0;
    s.y++;
  }
  if (!(s.s >> s.x & 1)) {
    s.s |= 1 << s.x;
    assert(valid(s.x, s.y, W, H));
    if (A[s.y][s.x] < 0) {
      s.t += abs(A[s.y][s.x]);
    } else {
      s.o = min(s.o + abs(A[s.y][s.x]), M);
    }
  }
}
void print(S s) {
  printf("x = %d y = %d o = %d s = %04X t = %d\n", s.x, s.y, s.o, s.s, s.t);
}

int main() {
  while (cin >> W >> H && W) {
    cin >> F >> M >> O;
    REP(y, H) REP(x, W) cin >> A[y][x];
    static int dist[10][10][51][1 << 10];
    REP(y, H) REP(x, W) REP(o, M + 1) REP(s, 1 << W) dist[y][x][o][s] = INF;
    if (O < 2) {
      cout << "NA" << endl;
      continue;
    }
    priority_queue<S> que;
    REP(sx, W) {
      S start(sx, -1, O, 0, 0);
      move(start, 0);
      update(start, dist);
      que.push(start);
    }
    int ans = -1;
    while (!que.empty()) {
      S s = que.top();
      que.pop();
      // print(s);
      if (s.y == H - 1) {
        ans = s.t;
        break;
      }
      if (dist[s.y][s.x][s.o][s.s] < s.t)
        continue;
      if (s.o <= 1)
        continue;
      for (int dx = -1; dx <= 1; dx++) {
        if (!(s.x + dx >= 0 && s.x + dx < W))
          continue;
        S next = s;
        move(next, dx);
        if (update(next, dist)) {
          que.push(next);
        }
      }
    }
    if (ans == -1 || ans > F)
      cout << "NA" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}