Problem p02587 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#define all(a) a.begin(), a.end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define pb push_back
#define debug(x) cerr << #x << ':' << (x) << '\n'
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;
typedef complex<ld> com;
constexpr int inf = 1000000010;
constexpr ll INF = 1000000000000000010;
constexpr ld eps = 1e-12;
constexpr ld pi = 3.141592653589793238;
template <class T, class U> inline bool chmax(T &a, const U &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T, class U> inline bool chmin(T &a, const U &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

typedef pair<ll, pair<string, int>> S;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;
  vector<string> s(n);
  vector<ll> c(n);
  vector<string> revs(n);
  rep(i, n) cin >> s[i] >> c[i];
  map<string, ll> mp;
  priority_queue<S, vector<S>, greater<S>> que;
  que.push({0, {"", 0}});
  que.push({0, {"", 1}});
  int f = 0;
  while (!que.empty()) {
    S p = que.top();
    que.pop();
    ll cost = p.first;
    string now = p.second.first;
    int mode = p.second.second;
    int len = now.size();
    if (cost != 0) {
      bool ok = true;
      rep(i, len) if (now[i] != now[len - 1 - i]) ok = false;
      if (ok) {
        cout << cost << '\n';
        return 0;
      }
    }
    f++;
    if (f > 1000000)
      break;
    if (cost > mp[now])
      continue;
    rep(i, n) {
      int sz = s[i].size();
      string tmp = s[i];
      if (mode == 0)
        reverse(all(tmp));
      if (now.size() >= sz && now.substr(0, sz) == tmp) {
        string rem = now.substr(sz);
        mp[rem] = cost + c[i];
        que.push({cost + c[i], {rem, mode}});
      }
      if (tmp.substr(0, len) == now) {
        string rem = tmp.substr(len);
        mp[rem] = cost + c[i];
        que.push({cost + c[i], {rem, mode ^ 1}});
      }
      reverse(all(tmp));
      if (now.size() + s[i].size() <= 20) {
        string m = now + tmp;
        mp[m] = cost + c[i];
        que.push({cost + c[i], {m, mode}});
      }
    }
  }
  cout << "-1\n";
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#define all(a) a.begin(), a.end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define pb push_back
#define debug(x) cerr << #x << ':' << (x) << '\n'
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;
typedef complex<ld> com;
constexpr int inf = 1000000010;
constexpr ll INF = 1000000000000000010;
constexpr ld eps = 1e-12;
constexpr ld pi = 3.141592653589793238;
template <class T, class U> inline bool chmax(T &a, const U &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T, class U> inline bool chmin(T &a, const U &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

typedef pair<ll, pair<string, int>> S;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;
  vector<string> s(n);
  vector<ll> c(n);
  vector<string> revs(n);
  rep(i, n) cin >> s[i] >> c[i];
  map<string, ll> mp;
  priority_queue<S, vector<S>, greater<S>> que;
  que.push({0, {"", 0}});
  que.push({0, {"", 1}});
  int f = 0;
  while (!que.empty()) {
    S p = que.top();
    que.pop();
    ll cost = p.first;
    string now = p.second.first;
    int mode = p.second.second;
    int len = now.size();
    if (cost != 0) {
      bool ok = true;
      rep(i, len) if (now[i] != now[len - 1 - i]) ok = false;
      if (ok) {
        cout << cost << '\n';
        return 0;
      }
    }
    f++;
    if (f > 1000000)
      break;
    if (cost > mp[now])
      continue;
    rep(i, n) {
      int sz = s[i].size();
      string tmp = s[i];
      if (mode == 0)
        reverse(all(tmp));
      if (now.size() >= sz && now.substr(0, sz) == tmp) {
        string rem = now.substr(sz);
        mp[rem] = cost + c[i];
        que.push({cost + c[i], {rem, mode}});
      }
      if (tmp.substr(0, len) == now) {
        string rem = tmp.substr(len);
        mp[rem] = cost + c[i];
        que.push({cost + c[i], {rem, mode ^ 1}});
      }
    }
  }
  cout << "-1\n";
}