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

#define _USE_MATH_DEFINES
#define INF 10000000
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>

using namespace std;

typedef long long ll;
typedef pair<int, vector<int>> P;

static const double eps = 1e-8;

int visited[15000000];

int conv(vector<int> &sets) {
  int res = 0;
  for (int i = 0; i < sets.size(); i++) {
    for (int j = 0; j <= 15; j++) {
      if (sets[i] & (1 << j)) {
        res += i * (pow(3.0, j) + eps);
      }
    }
  }
  return res;
}

int bfs(int m, vector<int> &root, int *visited) {

  priority_queue<P, vector<P>, greater<P>> que;
  que.push(P(0, root));
  visited[conv(root)] = 0;
  vector<int> tmp;
  vector<int> sets;
  while (!que.empty()) {
    int cost = que.top().first;

    sets = que.top().second;

    if (sets[1] == 0 && sets[2] == 0)
      return cost;
    if (sets[0] == 0 && sets[1] == 0)
      return cost;

    if (cost >= m)
      break;
    que.pop();
    for (int i = 0; i + 1 < sets.size(); i++) {
      if ((sets[i] && sets[i + 1] && sets[i] < sets[i + 1]) ||
          (!sets[i] && sets[i + 1])) {
        tmp = sets;

        int pos = 0;
        for (int j = 15; j >= 0; j--) {
          if (tmp[i + 1] & (1 << j)) {
            pos = j;
            break;
          }
        }
        tmp[i + 1] &= ~(1 << pos);
        tmp[i] |= (1 << pos);

        int next;
        if (visited[(next = conv(tmp))] == -1) {
          visited[next] = cost + 1;
          que.push(P(cost + 1, tmp));
        }
      }

      else if ((sets[i] && sets[i + 1] && sets[i] > sets[i + 1]) ||
               (sets[i] && !sets[i + 1])) {
        tmp = sets;

        int pos = 0;
        for (int j = 15; j >= 0; j--) {
          if (tmp[i] & (1 << j)) {
            pos = j;
            break;
          }
        }
        tmp[i] &= ~(1 << pos);
        tmp[i + 1] |= (1 << pos);

        int next;
        if (visited[(next = conv(tmp))] == -1) {
          visited[next] = cost + 1;
          que.push(P(cost + 1, tmp));
        }
      }
    }
  }
  return -1;
}

int main() {

  int n, m;
  while (~scanf("%d %d", &n, &m)) {
    if (n == m && m == 0)
      break;
    vector<int> sets(3);
    memset(visited, -1, sizeof(visited));
    for (int i = 0; i < 3; i++) {
      int amount;
      scanf("%d", &amount);
      for (int j = 0; j < amount; j++) {
        int size;
        scanf("%d", &size);
        sets[i] |= (1 << (size - 1));
      }
    }

    printf("%d\\n", bfs(m, sets, visited));
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 10000000
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <deque>
#include <hash_map>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>

using namespace std;

typedef long long ll;
typedef pair<int, vector<int>> P;

static const double eps = 1e-8;

int bfs(int m, vector<int> &root, map<string, int> visited) {

  priority_queue<P, vector<P>, greater<P>> que;
  que.push(P(0, root));

  vector<int> tmp;
  vector<int> sets;
  while (!que.empty()) {
    int cost = que.top().first;

    sets = que.top().second;

    if (sets[1] == 0 && sets[2] == 0)
      return cost;
    if (sets[0] == 0 && sets[1] == 0)
      return cost;

    if (cost >= m)
      break;
    que.pop();
    for (int i = 0; i + 1 < sets.size(); i++) {
      if ((sets[i] && sets[i + 1] && sets[i] < sets[i + 1]) ||
          (!sets[i] && sets[i + 1])) {
        tmp = sets;

        int pos = 0;
        for (int j = 15; j >= 0; j--) {
          if (tmp[i + 1] & (1 << j)) {
            pos = j;
            break;
          }
        }
        tmp[i + 1] &= ~(1 << pos);
        tmp[i] |= (1 << pos);

        char buf[32];
        sprintf(buf, "%09d%09d%09d", tmp[0], tmp[1], tmp[2]);
        string next;
        next = buf;
        if (visited.find(next) == visited.end()) {
          visited[next] = cost + 1;
          que.push(P(cost + 1, tmp));
        }
      }

      else if ((sets[i] && sets[i + 1] && sets[i] > sets[i + 1]) ||
               (sets[i] && !sets[i + 1])) {
        tmp = sets;

        int pos = 0;
        for (int j = 15; j >= 0; j--) {
          if (tmp[i] & (1 << j)) {
            pos = j;
            break;
          }
        }
        tmp[i] &= ~(1 << pos);
        tmp[i + 1] |= (1 << pos);

        char buf[32];
        sprintf(buf, "%09d%09d%09d", tmp[0], tmp[1], tmp[2]);
        string next;
        next = buf;
        if (visited.find(next) == visited.end()) {
          visited[next] = cost + 1;
          que.push(P(cost + 1, tmp));
        }
      }
    }
  }
  return -1;
}

int main() {

  int n, m;
  while (~scanf("%d %d", &n, &m)) {
    if (n == m && m == 0)
      break;
    vector<int> sets(3);
    map<string, int> visited;
    for (int i = 0; i < 3; i++) {
      int amount;
      scanf("%d", &amount);
      for (int j = 0; j < amount; j++) {
        int size;
        scanf("%d", &size);
        sets[i] |= (1 << (size - 1));
      }
    }

    printf("%d\\n", bfs(m, sets, visited));
  }
}