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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

#define INF (1 << 30)

#define MASK ((1LL << (4 * 9)) - 1)
#define BWB (1LL << (4 * 10))

/* typedef */

typedef long long ll;
typedef vector<ll> vl;
typedef map<ll, int> mli;

/* global variables */

// ## pos&mv
// ##   x y z
// ## c 0 1 2 a
// ## a 3 4 5 b
// ## b 6 7 8 c
// ##   x y z

int nbrs[9][4] = {
    // R, L, U, D
    {1, 8, 6, 3}, // 0
    {2, 0, 7, 4}, // 1
    {3, 1, 8, 5}, // 2
    {4, 2, 0, 6}, // 3
    {5, 3, 1, 7}, // 4
    {6, 4, 2, 8}, // 5
    {7, 5, 3, 0}, // 6
    {8, 6, 4, 1}, // 7
    {0, 7, 5, 2}, // 8
};

mli dists;

struct g_dist {
  bool operator()(const ll &a, const ll &b) const {
    return dists[b] < dists[a];
  }
};

/* subroutines */

ll read() {
  int bpos = 0, pos = 0;
  ll flds = 0;

  for (int y = 0; y < 3; y++) {
    for (int x = 0; x < 3; x++) {
      int d;
      cin >> d;
      flds |= (ll)d << (pos * 4);
      if (d == 0)
        bpos = pos;
      pos++;
    }
  }

  return (flds | (ll)bpos << (9 * 4));
}

/* main */

int main() {
  int ch, cv;
  ll st, gl;

  for (;;) {
    cin >> ch >> cv;
    if ((ch | cv) == 0)
      break;

    st = read();
    gl = read() | BWB;

    dists.clear();
    dists[st] = dists[gl] = 0;

    priority_queue<ll, vl, g_dist> q;
    q.push(st);
    q.push(gl);

    int min_cost = INF;
    int min_check = 10;

    while (!q.empty()) {
      ll u = q.top();
      q.pop();

      bool bwd = ((u & BWB) != 0);

      if ((!bwd && dists.find(u | BWB) != dists.end()) ||
          (bwd && dists.find(u & ~BWB) != dists.end())) {
        int c = dists[u | BWB] + dists[u & ~BWB];
        if (min_cost > c)
          min_cost = c;
        if (--min_check <= 0)
          break;
      }

      int ud = dists[u];
      int upos = (u >> (9 * 4)) & 0xf;

      for (int i = 0; i < 4; i++) {
        int vpos = nbrs[upos][i];
        int nvd = ud + (i < 2 ? ch : cv);

        int k = (u >> (vpos * 4)) & 0xf;
        ll v = (u & (MASK | BWB) & ~(0xfLL << (vpos * 4))) |
               ((ll)k << (upos * 4)) | ((ll)vpos << (4 * 9));

        if (dists.find(v) == dists.end()) {
          dists[v] = nvd;
          q.push(v);
        } else if (dists[v] > nvd) {
          dists[v] = nvd;
        }
      }
    }

    cout << min_cost << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

#define INF (1 << 30)
#define MASK ((1LL << (4 * 9)) - 1)

/* typedef */

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;
typedef map<ll, int> mli;

/* global variables */

// ## pos&mv
// ##   x y z
// ## c 0 1 2 a
// ## a 3 4 5 b
// ## b 6 7 8 c
// ##   x y z

int nbrs[9][4] = {
    // R, L, U, D
    {1, 8, 6, 3}, // 0
    {2, 0, 7, 4}, // 1
    {3, 1, 8, 5}, // 2
    {4, 2, 0, 6}, // 3
    {5, 3, 1, 7}, // 4
    {6, 4, 2, 8}, // 5
    {7, 5, 3, 0}, // 6
    {8, 6, 4, 1}, // 7
    {0, 7, 5, 2}, // 8
};

mli dists;

struct g_dist {
  bool operator()(const ll &a, const ll &b) const {
    return dists[b] < dists[a];
  }
};

/* subroutines */

ll read() {
  int bpos = -1, pos = 0;
  ll flds = 0;

  for (int y = 0; y < 3; y++) {
    for (int x = 0; x < 3; x++) {
      int d;
      cin >> d;
      flds |= (ll)d << (pos * 4);
      if (d == 0)
        bpos = pos;
      pos++;
    }
  }

  return flds | (ll)bpos << (9 * 4);
}

/* main */

int main() {
  int ch, cv;
  ll st, gl;

  for (;;) {
    cin >> ch >> cv;
    if ((ch | cv) == 0)
      break;

    st = read();
    gl = read();

    dists.clear();
    dists[st] = 0;

    priority_queue<ll, vl, g_dist> q;
    q.push(st);

    while (!q.empty()) {
      ll u = q.top();
      q.pop();

      if (u == gl)
        break;

      int ud = dists[u];
      int upos = u >> (9 * 4);

      for (int i = 0; i < 4; i++) {
        int vpos = nbrs[upos][i];
        int nvd = ud + (i < 2 ? ch : cv);

        int k = (u >> (vpos * 4)) & 0xf;
        ll v = (u & MASK & ~(0xfLL << (vpos * 4))) | ((ll)k << (upos * 4)) |
               ((ll)vpos << (4 * 9));

        if (dists.find(v) == dists.end()) {
          dists[v] = nvd;
          q.push(v);
        } else if (dists[v] > nvd) {
          dists[v] = nvd;
        }
      }
    }

    cout << dists[gl] << endl;
  }

  return 0;
}