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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)

int hor[9][2] = {{1, 8}, {0, 2}, {1, 3}, {2, 4}, {3, 5},
                 {4, 6}, {5, 7}, {6, 8}, {0, 7}};

int _pow10[10] = {1,      10,      100,      1000,      10000,
                  100000, 1000000, 10000000, 100000000, 1000000000};

struct A {
  int cost;
  int emp;
  long long s;
  bool operator<(const A &a) const { return s < a.s; }
};

int main() {
  int ch, cv;
  while (cin >> ch >> cv, ch | cv) {
    map<long long, int> mincost;
    map<long long, int>::iterator it;
    long long start = 0, goal = 0;
    int emp;
    rep(i, 9) {
      int a;
      cin >> a;
      start += a * _pow10[i];
      if (a == 0)
        emp = i;
    }
    rep(i, 9) {
      int a;
      cin >> a;
      goal += a * _pow10[i];
    }
    A a;
    a.cost = 0;
    a.emp = emp;
    a.s = start;
    queue<A> q;
    q.push(a);
    mincost[start] = 0;
    int ans = 1000000000;
    if (start == goal)
      ans = 0;
    while (!q.empty()) {
      a = q.front();
      q.pop();
      if (mincost[a.s] < a.cost || ans <= a.cost)
        continue;
      int e = a.emp;
      rep(i, 2) {
        a.cost += ch;
        a.emp = hor[e][i];
        int x = a.s / _pow10[hor[e][i]] % 10;
        a.s += x * _pow10[e] - x * _pow10[hor[e][i]];
        it = mincost.find(a.s);
        if (a.cost < ans && (it == mincost.end() || a.cost < it->second)) {
          mincost[a.s] = a.cost;
          q.push(a);
          if (a.s == goal)
            ans = min(ans, a.cost);
        }
        a.cost -= ch;
        a.emp = e;
        a.s -= x * _pow10[e] - x * _pow10[hor[e][i]];
      }
      rep(i, 2) {
        int ver = (e + 3 + i * 3) % 9;
        a.cost += cv;
        a.emp = ver;
        int x = a.s / _pow10[ver] % 10;
        a.s += x * _pow10[e] - x * _pow10[ver];
        it = mincost.find(a.s);
        if (a.cost < ans && (it == mincost.end() || a.cost < it->second)) {
          mincost[a.s] = a.cost;
          q.push(a);
          if (a.s == goal)
            ans = min(ans, a.cost);
        }
        a.cost -= cv;
        a.emp = e;
        a.s -= x * _pow10[e] - x * _pow10[ver];
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)

int hor[9][2] = {{1, 8}, {0, 2}, {1, 3}, {2, 4}, {3, 5},
                 {4, 6}, {5, 7}, {6, 8}, {0, 7}};

struct A {
  int cost;
  int emp;
  string s;
  bool operator<(const A &a) const { return cost > a.cost; }
};

int main() {
  int ch, cv;
  while (cin >> ch >> cv, ch | cv) {
    map<string, int> mincost;
    map<string, int>::iterator it;
    string start, goal;
    int emp;
    rep(i, 9) {
      int a;
      cin >> a;
      start += '0' + a;
      if (a == 0)
        emp = i;
    }
    rep(i, 9) {
      int a;
      cin >> a;
      goal += '0' + a;
    }
    A a;
    a.cost = 0;
    a.emp = emp;
    a.s = start;
    priority_queue<A> pq;
    pq.push(a);
    mincost[start] = 0;
    int ans = 1000000000;
    while (!pq.empty()) {
      a = pq.top();
      pq.pop();
      if (mincost[a.s] < a.cost || ans <= a.cost)
        continue;
      if (a.s == goal) {
        ans = a.cost;
        break;
      }
      int e = a.emp;
      rep(i, 2) {
        a.cost += ch;
        a.emp = hor[e][i];
        swap(a.s[e], a.s[hor[e][i]]);
        it = mincost.find(a.s);
        if (a.cost < ans && (it == mincost.end() || a.cost < it->second)) {
          mincost[a.s] = a.cost;
          pq.push(a);
          if (a.s == goal)
            ans = a.cost;
        }
        a.cost -= ch;
        a.emp = e;
        swap(a.s[e], a.s[hor[e][i]]);
      }
      rep(i, 2) {
        int ver = (e + 3 + i * 3) % 9;
        a.cost += cv;
        a.emp = ver;
        swap(a.s[e], a.s[ver]);
        it = mincost.find(a.s);
        if (a.cost < ans && (it == mincost.end() || a.cost < it->second)) {
          mincost[a.s] = a.cost;
          pq.push(a);
          if (a.s == goal)
            ans = a.cost;
        }
        a.cost -= cv;
        a.emp = e;
        swap(a.s[e], a.s[ver]);
      }
    }
    cout << ans << endl;
  }
  return 0;
}