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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <class Tuple, unsigned Index>
void print_tuple(ostream &os, const Tuple &t) {}

template <class Tuple, unsigned Index, class Type, class... Types>
void print_tuple(ostream &os, const Tuple &t) {
  if (Index > 0)
    os << ", ";
  os << get<Index>(t);
  print_tuple<Tuple, Index + 1, Types...>(os, t);
}

template <class... Types>
ostream &operator<<(ostream &os, const tuple<Types...> &t) {
  os << '(';
  print_tuple<tuple<Types...>, 0, Types...>(os, t);
  return os << ')';
}

template <class Iterator>
ostream &dump_range(ostream &, Iterator, const Iterator &);

template <typename T> ostream &operator<<(ostream &os, vector<T> c) {
  return dump_range(os, c.cbegin(), c.cend());
}

template <class Iterator>
ostream &dump_range(ostream &os, Iterator first, const Iterator &last) {
  os << '[';
  for (int i = 0; first != last; ++i, ++first) {
    if (i)
      os << ", ";
    os << *first;
  }
  return os << ']';
}

enum FACE { TOP, BOTTOM, NORTH, SOUTH, WEST, EAST };

class dice {
private:
  int num[6];

public:
  inline void roll(FACE a, FACE b, FACE c, FACE d) {
    swap(num[a], num[b]);
    swap(num[b], num[c]);
    swap(num[c], num[d]);
  }

  dice() {
    num[TOP] = 1;
    num[BOTTOM] = 6;
    num[NORTH] = 5;
    num[SOUTH] = 2;
    num[EAST] = 3;
    num[WEST] = 4;
  }

  dice(const dice &d) {
    num[TOP] = d[TOP];
    num[BOTTOM] = d[BOTTOM];
    num[NORTH] = d[NORTH];
    num[SOUTH] = d[SOUTH];
    num[EAST] = d[EAST];
    num[WEST] = d[WEST];
  }

  int encode() const {
    return (num[TOP] - 1) * 6 * 6 + (num[NORTH] - 1) * 6 + (num[EAST] - 1);
  }

  const int &operator[](FACE f) const { return num[f]; }
};

void north(dice &d) { d.roll(TOP, SOUTH, BOTTOM, NORTH); }
void east(dice &d) { d.roll(TOP, WEST, BOTTOM, EAST); }
void west(dice &d) { d.roll(TOP, EAST, BOTTOM, WEST); }
void south(dice &d) { d.roll(TOP, NORTH, BOTTOM, SOUTH); }

constexpr int MAX_SIZE = 10;
constexpr int INF = 0xfffffff;
int h, w;
int gx, gy;
int field[MAX_SIZE][MAX_SIZE];

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void (*func[4])(dice &d) = {east, south, west, north};

bool visited[MAX_SIZE][MAX_SIZE][6];

bool out(int x, int y) { return x < 0 || x >= w || y < 0 || y >= h; }

typedef int weight;
vector<weight> dist;
struct state {
  int x, y;
  dice d;
  weight dist;
  state(int x, int y, const dice &d, weight dist)
      : x(x), y(y), d(d), dist(dist) {}

  bool operator>(const state &s) const { return dist > s.dist; }
};

weight dijkstra(int sx, int sy, dice d) {
  priority_queue<state, vector<state>, greater<state>> que;
  vector<vector<vector<weight>>> dist(
      h, vector<vector<weight>>(w, vector<weight>(6 * 6 * 6, INF)));
  dist[sy][sx][d.encode()] = 0;
  que.push(state(sx, sy, d, 0));

  while (!que.empty()) {
    const state s = que.top();
    que.pop();

    if (dist[s.y][s.x][s.d.encode()] < s.dist)
      continue;

    if (s.x == gx && s.y == gy)
      return s.dist;

    for (int i = 0; i < 4; ++i) {
      const int nx = s.x + dx[i];
      const int ny = s.y + dy[i];
      if (out(nx, ny))
        continue;
      dice next_d(s.d);
      func[i](next_d);
      const int next_dist = s.dist + next_d[BOTTOM] * field[ny][nx];
      if (dist[ny][nx][next_d.encode()] > next_dist) {
        dist[ny][nx][next_d.encode()] = next_dist;
        que.push(state(nx, ny, next_d, next_dist));
      }
    }
  }

  return -1;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  memset(visited, false, sizeof(visited));

  while (cin >> h >> w && h) {
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        cin >> field[i][j];
      }
    }

    int sx, sy;
    cin >> sy >> sx >> gy >> gx;

    cout << dijkstra(sx, sy, dice()) << endl;
  }

  return EXIT_SUCCESS;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <class Tuple, unsigned Index>
void print_tuple(ostream &os, const Tuple &t) {}

template <class Tuple, unsigned Index, class Type, class... Types>
void print_tuple(ostream &os, const Tuple &t) {
  if (Index > 0)
    os << ", ";
  os << get<Index>(t);
  print_tuple<Tuple, Index + 1, Types...>(os, t);
}

template <class... Types>
ostream &operator<<(ostream &os, const tuple<Types...> &t) {
  os << '(';
  print_tuple<tuple<Types...>, 0, Types...>(os, t);
  return os << ')';
}

template <class Iterator>
ostream &dump_range(ostream &, Iterator, const Iterator &);

template <typename T> ostream &operator<<(ostream &os, vector<T> c) {
  return dump_range(os, c.cbegin(), c.cend());
}

template <class Iterator>
ostream &dump_range(ostream &os, Iterator first, const Iterator &last) {
  os << '[';
  for (int i = 0; first != last; ++i, ++first) {
    if (i)
      os << ", ";
    os << *first;
  }
  return os << ']';
}

enum FACE { TOP, BOTTOM, NORTH, SOUTH, WEST, EAST };

class dice {
private:
  int num[6];

public:
  inline void roll(FACE a, FACE b, FACE c, FACE d) {
    swap(num[a], num[b]);
    swap(num[b], num[c]);
    swap(num[c], num[d]);
  }

  dice() {
    num[TOP] = 1;
    num[BOTTOM] = 6;
    num[NORTH] = 5;
    num[SOUTH] = 2;
    num[EAST] = 3;
    num[WEST] = 4;
  }

  dice(const dice &d) {
    num[TOP] = d[TOP];
    num[BOTTOM] = d[BOTTOM];
    num[NORTH] = d[NORTH];
    num[SOUTH] = d[SOUTH];
    num[EAST] = d[EAST];
    num[WEST] = d[WEST];
  }

  const int &operator[](FACE f) const { return num[f]; }
};

void north(dice &d) { d.roll(TOP, SOUTH, BOTTOM, NORTH); }
void east(dice &d) { d.roll(TOP, WEST, BOTTOM, EAST); }
void west(dice &d) { d.roll(TOP, EAST, BOTTOM, WEST); }
void south(dice &d) { d.roll(TOP, NORTH, BOTTOM, SOUTH); }

constexpr int MAX_SIZE = 10;
constexpr int INF = 0xfffffff;
int h, w;
int gx, gy;
int field[MAX_SIZE][MAX_SIZE];

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void (*func[4])(dice &d) = {east, south, west, north};

bool visited[MAX_SIZE][MAX_SIZE][6];

bool out(int x, int y) { return x < 0 || x >= w || y < 0 || y >= h; }

int dfs(int x, int y, dice d) {
  if (x == gx && y == gy)
    return 0;
  if (visited[y][x][d[TOP] - 1])
    return INF;
  visited[y][x][d[TOP] - 1] = true;

  int res = INF;

  for (int i = 0; i < 4; ++i) {
    const int nx = x + dx[i];
    const int ny = y + dy[i];
    if (out(nx, ny))
      continue;

    dice next_d(d);
    func[i](next_d);
    chmin(res, dfs(nx, ny, next_d) + next_d[BOTTOM] * field[ny][nx]);
  }

  visited[y][x][d[TOP] - 1] = false;

  return res;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  memset(visited, false, sizeof(visited));

  while (cin >> h >> w && h) {
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
        cin >> field[i][j];
      }
    }

    int sx, sy;
    cin >> sy >> sx >> gy >> gx;

    cout << dfs(sx, sy, dice()) << endl;
  }

  return EXIT_SUCCESS;
}