Language: C++

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i)
#define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i)
#define m_p make_pair

namespace IO {
    #define gc getchar()
    template <typename T>
    inline void read(T& x) {
        x = 0; bool f = 1; char ch;
        for (ch = gc; ch < '0' || '9' < ch; ch = gc) if (ch == '-') f ^= 1;
        for (; '0' <= ch && ch <= '9'; ch = gc) x = (x << 3) + (x << 1) + (ch ^ 48);
        x = f ? x : -x;
    }
    #undef gc
}

typedef long long ll;

const int MAXN = 2000 + 10;

template <typename T>
bool chkmin(T& a, T b) { if (a > b) return a = b, true; return false; }
template <typename T>
bool chkmax(T& a, T b) { if (a < b) return a = b, true; return false; }

int n;
string str[MAXN], id_to_str[MAXN];
bool is_palindrome[MAXN];
unordered_map<string, int> str_to_id;
ll val[MAXN], ans = LONG_LONG_MAX, dis[2][MAXN], vis[2][MAXN];

typedef pair<int, int> Node;
typedef pair<ll, Node > plii;

priority_queue<plii, vector<plii>, greater<plii> > que;

bool starts_with(string& a, string& b) {
    if (a.size() < b.size()) return false;
    rep(i, 0, b.size() - 1) if (a[i] != b[i]) return false;
    return true;
}

Node trans(int flg, string u, string v) {
    Node ret; ret.first = 0, ret.second = 0;
    string res;
    if (flg == 0) reverse(v.begin(), v.end()), res = u;
    else reverse(u.begin(), u.end()), res = v;
    if (flg == 0 && starts_with(u, v) || flg == 1 && starts_with(v, u)) {
        ret.first = 0;
        if (flg == 1) res = v.substr(u.size(), v.size() - u.size() + 1);
        else res = u.substr(v.size(), u.size() - v.size() + 1);
    } else if (flg == 0 && starts_with(v, u) || flg == 1 && starts_with(u, v)) {
        ret.first = 1;
        if (flg == 0) res = v.substr(u.size(), v.size() - u.size() + 1);
        else res = u.substr(v.size(), u.size() - v.size() + 1);
        reverse(res.begin(), res.end());
    } else {
        ret.first = -1;
        return ret;
    }
    if (!str_to_id.count(res)) ret,first = -1;
    ret.second = str_to_id[res];
    return ret;
}

int main() {
    IO::read(n);
    str_to_id[""] = 0;
    rep(i, 1, n) {
        cin >> str[i]; IO::read(val[i]);
        string cur; cur.clear();
        rep(j, 0, str[i].size() - 1) {
            cur.push_back(str[i][j]);
            if (!str_to_id.count(cur)) {
                int _sz = str_to_id.size();
                str_to_id[cur] = _sz;
            }
        }
        cur.clear();
        per(j, str[i].size() - 1, 0) {
            cur.push_back(str[i][j]);
            if (!str_to_id.count(cur)) {
                int _sz = str_to_id.size();
                str_to_id[cur] = _sz;
            }
        }
    }
    for (auto _cur : str_to_id) {
        string cur = _cur.first;
        string ruc = cur;
        id_to_str[_cur.second] = cur;
        reverse(ruc.begin(), ruc.end());
        is_palindrome[_cur.second] = (cur == ruc);
    }
    rep(i, 0, str_to_id.size()) dis[0][i] = dis[1][i] = LONG_LONG_MAX >> 1;
    rep(i, 1, n) {
        if (is_palindrome[str_to_id[str[i]]]) ans = min(ans, val[i]);
        chkmin(dis[0][str_to_id[str[i]]], val[i]);
        chkmin(dis[1][str_to_id[str[i]]], val[i]);
        que.push(m_p(val[i], m_p(0, str_to_id[str[i]])));
        que.push(m_p(val[i], m_p(1, str_to_id[str[i]])));
    }
    while (!que.empty()) {
        plii u = que.top(); que.pop();
        if (vis[u.second.first][u.second.second]) continue;
        vis[u.second.first][u.second.second] = true;
        rep(i, 1, n) {
            Node v = trans(u.second.first, id_to_str[u.second.second], str[i]);
            if (v.first == -1) continue;
            if (chkmin(dis[v.first][v.second], dis[u.second.first][u.second.second] + val[i])) {
                que.push(m_p(dis[v.first][v.second], v));
            }
        }
    }
    rep(i, 0, str_to_id.size()) {
        if (is_palindrome[i]) chkmin(ans, min(dis[0][i], dis[1][i]));
    }
    if (ans >= (LONG_LONG_MAX >> 1)) { puts("-1"); return 0; }
    printf("%lld\n", ans);
    return 0;
}

Compiler output:
a.cc: In function 'Node trans(int, std::string, std::string)':
a.cc:64:36: error: 'first' was not declared in this scope
   64 |     if (!str_to_id.count(res)) ret,first = -1;
      |                                    ^~~~~