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

#include <bits/stdc++.h>

using namespace std;

const int N = 362880;

map<int, int> mp;
int H[9][2] = {{2, 9}, {3, 1}, {4, 2}, {5, 3}, {6, 4},
               {7, 5}, {8, 6}, {9, 7}, {8, 1}};
int V[9][2] = {{7, 4}, {8, 5}, {9, 6}, {1, 7}, {2, 8},
               {3, 9}, {4, 1}, {5, 2}, {6, 3}};

bool vis[N];
queue<int> q;
int ch, cv, a[9], b[9], p[9], dis[N], f[N], Gh[N][2], Gv[N][2];

int Trans(int *a) {
  int res = 0;
  for (int i = 0; i < 9; i++)
    res = res * 10 + a[i];
  return mp[res];
}

int RTrans(int x, int *p) {
  int y = f[x], pos;
  for (int i = 8; i >= 0; i--, y /= 10) {
    p[i] = y % 10;
    if (p[i] == 0)
      pos = i;
  }
  return pos;
}

void Init() {
  int cnt = 0, per[9], p[9];
  for (int i = 0; i < 9; i++)
    for (int j = 0; j < 2; j++)
      H[i][j]--, V[i][j]--;
  for (int i = 0; i < 9; i++)
    per[i] = i;

  do {
    int res = 0;
    for (int i = 0; i < 9; i++)
      res = res * 10 + per[i];
    f[cnt] = res, mp[res] = cnt++;
  } while (next_permutation(per, per + 9));

  for (int i = 0; i < cnt; i++) {
    int pos = RTrans(i, p);
    for (int j = 0; j < 2; j++) {
      swap(p[pos], p[H[pos][j]]), Gh[i][j] = Trans(p),
                                  swap(p[pos], p[H[pos][j]]);
      swap(p[pos], p[V[pos][j]]), Gv[i][j] = Trans(p),
                                  swap(p[pos], p[V[pos][j]]);
    }
  }
  assert(cnt == 362880);
}

void AddPoint(int v, int d) {
  if (dis[v] > d) {
    dis[v] = d;
    if (!vis[v])
      vis[v] = 1, q.push(v);
  }
}

int SPFA() {
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < N; i++)
    dis[i] = (1 << 30);
  int pa = Trans(a), pb = Trans(b);

  for (vis[pa] = 1, dis[pa] = 0, q.push(pa); !q.empty(); q.pop()) {
    int u = q.front();
    for (int i = 0; i < 2; i++)
      AddPoint(Gh[u][i], dis[u] + ch), AddPoint(Gv[u][i], dis[u] + cv);
    vis[u] = 0;
  }
  return dis[pb];
}

int main() {
  for (Init(); cin >> ch >> cv, ch;) {
    for (int i = 0; i < 9; i++)
      scanf("%d", a + i);
    for (int i = 0; i < 9; i++)
      scanf("%d", b + i);
    cout << SPFA() << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int N = 362880;

map<int, int> mp;
int H[9][2] = {{2, 9}, {3, 1}, {4, 2}, {5, 3}, {6, 4},
               {7, 5}, {8, 6}, {9, 7}, {8, 1}};
int V[9][2] = {{7, 4}, {8, 5}, {9, 6}, {1, 7}, {2, 8},
               {3, 9}, {4, 1}, {5, 2}, {6, 3}};

bool vis[N];
queue<int> q;
int ch, cv, a[9], b[9], p[9], dis[N], f[N];

void Init() {
  int cnt = 0, per[9];
  for (int i = 0; i < 9; i++)
    for (int j = 0; j < 2; j++)
      H[i][j]--, V[i][j]--;
  for (int i = 0; i < 9; i++)
    per[i] = i;

  do {
    int res = 0;
    for (int i = 0; i < 9; i++)
      res = res * 10 + per[i];
    f[cnt] = res, mp[res] = cnt++;
  } while (next_permutation(per, per + 9));

  assert(cnt == 362880);
}

int Trans(int *a) {
  int res = 0;
  for (int i = 0; i < 9; i++)
    res = res * 10 + a[i];
  return mp[res];
}

int RTrans(int x, int *p) {
  int y = f[x], pos;
  for (int i = 8; i >= 0; i--, y /= 10) {
    p[i] = y % 10;
    if (p[i] == 0)
      pos = i;
  }
  return pos;
}

void AddPoint(int v, int d) {
  if (dis[v] > d) {
    dis[v] = d;
    if (!vis[v])
      vis[v] = 1, q.push(v);
  }
}

int SPFA() {
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < N; i++)
    dis[i] = (1 << 30);
  int pa = Trans(a), pb = Trans(b);

  for (vis[pa] = 1, dis[pa] = 0, q.push(pa); !q.empty(); q.pop()) {
    int u = q.front();
    int pos = RTrans(u, p);
    for (int i = 0; i < 2; i++) {
      int v = H[pos][i];
      swap(p[pos], p[v]);

      AddPoint(Trans(p), dis[u] + ch), swap(p[pos], p[v]);
    }
    for (int i = 0; i < 2; i++) {
      int v = V[pos][i];
      swap(p[pos], p[v]);

      AddPoint(Trans(p), dis[u] + cv), swap(p[pos], p[v]);
    }
    vis[u] = 0;
  }
  return dis[pb];
}

int main() {
  for (Init(); cin >> ch >> cv, ch;) {
    for (int i = 0; i < 9; i++)
      scanf("%d", a + i);
    for (int i = 0; i < 9; i++)
      scanf("%d", b + i);
    cout << SPFA() << endl;
  }
}