Language: C++

// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // codeforces
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native") // yandex

#include "bits/stdc++.h"
using namespace std;
#ifndef LOCAL
#define endl '\n'
#endif

#define fr(i, a, b) for(int i = a; i <= b; i++)
#define rf(i, a, b) for(int i = a; i >= b; i--)
#define pf push_front
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound

typedef long long ll;
typedef long double f80;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int pct(int x) { return __builtin_popcount(x); }
int pct(ll x) { return __builtin_popcountll(x); }
int bt(int x) { return 31 - __builtin_clz(x); } // floor(log2(x))
int bt(ll x) { return 63 - __builtin_clzll(x); } // floor(log2(x))
int cdiv(int a, int b) { return a / b + !(a < 0 || a % b == 0); }
ll cdiv(ll a, ll b) { return a / b + !(a < 0 || a % b == 0); }
int nxt_C(int x) { int c = x & -x, r = x + c; return (((r ^ x) >> 2) / c) | r; }
ll nxt_C(ll x) { ll c = x & -x, r = x + c; return (((r ^ x) >> 2) / c) | r; }

vector<int> get_bits(int mask) {
	vector<int> bb;
	while(mask) { int b = bt(mask); bb.pb(b); mask ^= (1 << b); }
	reverse(all(bb));
	return bb;
}

int get_mask(vector<int> v) {
	int mask = 0;
	for(int x : v) { mask ^= (1 << x); }
	return mask;
}

template<typename T>
void uniq(vector<T> &v) { sort(all(v)); v.resize(unique(all(v)) - v.begin()); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

ll rand(ll l, ll r){
	uniform_int_distribution<ll> uid(l, r);
	return uid(rng);
}

void sc() {}

template <typename Head, typename... Tail>
void sc(Head &H, Tail &... T) { cin >> H; sc(T...); }

#ifdef LOCAL
#define debug(...) cerr << "[L:" << __LINE__ << "][" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

// #ifndef LOCAL
// string to_string(__int128 x) {
// 	string s = "";
// 	bool neg = 0;
// 	if(x < 0) { s += "-"; neg = 1; x = -x; }
// 	if(!x) s += '0';
// 	while(x) {
// 		int rem = x % 10;
// 		s += to_string(rem);
// 		x /= 10;
// 	}
// 	reverse(s.begin() + neg, s.end());
// 	return s;
// }
// #endif

const int mod = 1e9 + 7; // 998244353;

int pwr(int a,ll b) {
	int ans = 1;
	while(b) {
		if(b & 1) ans = (ans * 1LL * a) % mod;
		a = (a * 1LL * a) % mod;
		b >>= 1;
	}
	return ans;
}

/*
	Lookout for overflows!!
	Check array sizes!!
	Clear before test cases!!
	Use the correct modulo!!
	Check for corner cases!!
	Are you forgetting something?!
	Read problem statement carefully!!!
*/

const int N = 55;
string s[N];
ll cost[N];
const int NN = 4005;
vector<pair<pii,int>> g[NN][2];
string ss[NN];
vector<int> z[N][2];
bool ter[NN];
ll dist[NN][2];
ll cost1[NN];

void solve() {
	int n;
    sc(n);
    fr(i, 1, n) {
        sc(s[i]);
        sc(cost[i]);
    }
    int c = 0;
    fr(i, 1, n) {
        z[i][0].pb(0);
        z[i][1].pb(0);
        fr(j, 1, sz(s[i])) {
            ss[++c] = s[i].substr(0, j);
            z[i][0].pb(c);
            cost1[c] = cost[i];
        }
        fr(j, 1, sz(s[i])) {
            ss[++c] = s[i].substr(sz(s[i]) - j, j);
            z[i][1].pb(c);
            cost1[c] = cost[i];
        }
    }
    for(int i = 1; i <= c; i++) {
        for(int j = 1; j <= n; j++) {
            if(sz(ss[i]) > sz(s[j])) {
                string s2 = s[j];
                reverse(all(s2));
                if(s2 == ss[i].substr(sz(ss[i]) - sz(s2), sz(s2))) {
                    int ii = i - sz(s2);
                    g[ii][0].pb({{i, 0}, cost[j]});
                }
            }
            else if(sz(ss[i]) <= sz(s[j])) {
                string s1 = ss[i];
                reverse(all(s1));
                if(s1 == s[j].substr(0, sz(s1))) {
                    int ii = z[j][1][sz(s[j]) - sz(s1)];
                    g[ii][1].pb({{i, 0}, cost[j]});
                }
            }
            if(sz(ss[i]) > sz(s[j])) {
                string s2 = s[j];
                reverse(all(s2));
                if(s2 == ss[i].substr(0, sz(s2))) {
                    int ii = i - sz(s2);
                    g[ii][1].pb({{i, 1}, cost[j]});
                }
            }
            else if(sz(ss[i]) <= sz(s[j])) {
                string s1 = ss[i];
                reverse(all(s1));
                if(s1 == s[j].substr(sz(s[j]) - sz(s1), sz(s1))) {
                    int ii = z[j][0][sz(s[j]) - sz(s1)];
                    g[ii][0].pb({{i, 0}, cost[j]});
                }
            }
        }
    }
    ll ans = 1e18;
    fr(i, 1, n) {
        for(int j = 0; 2 * j <= sz(s[i]); j++) {
            string s1 = s[i].substr(0, sz(s[i]) - j);
            string s2 = s[i].substr(sz(s[i]) - j, j);
            reverse(all(s1));
            if(s1 == s2) {
                ans = min(ans, cost[i]);
            }
            else if(s1.substr(0, sz(s2)) == s2) {
                ter[z[i][0][sz(s[i]) - 2 * j]] = 1;
            }
        }
        for(int j = 0; 2 * j + 1 <= sz(s[i]); j++) {
            string s1 = s[i].substr(0, sz(s[i]) - j - 1);
            string s2 = s[i].substr(sz(s[i]) - j, j);
            reverse(all(s1));
            if(s1 == s2) {
                ans = min(ans, cost[i]);
            }
            else if(s1.substr(0, sz(s2)) == s2) {
                ter[z[i][0][sz(s[i]) - (2 * j + 1)]] = 1;
            }
        }
        for(int j = 0; 2 * j <= sz(s[i]); j++) {
            string s1 = s[i].substr(0, j);
            string s2 = s[i].substr(j, sz(s[i]) - j);
            reverse(all(s1));
            if(s1 == s2) {
                ans = min(ans, cost[i]);
            }
            else if(s2.substr(0, sz(s1)) == s1) {
                ter[z[i][1][sz(s[i]) - (2 * j)]] = 1;
            }
        }
        for(int j = 0; 2 * j + 1 <= sz(s[i]); j++) {
            string s1 = s[i].substr(0, j);
            string s2 = s[i].substr(j + 1, sz(s[i]) - j);
            reverse(all(s1));
            if(s1 == s2) {
                ans = min(ans, cost[i]);
            }
            else if(s2.substr(0, sz(s1)) == s1) {
                ter[z[i][1][sz(s[i]) - (2 * j + 1)]] = 1;
            }
        }
    }
    set<pair<ll,pii>> q;
    q.insert({0, {0, 0}});
    q.insert({0, {0, 1}});
    fr(i, 1, c) {
        dist[i][0] = dist[i][1] = 1e18;
    }
    while(!q.empty()) {
        auto x = *q.begin();
        q.erase(q.begin());
        if(x.fi > dist[x.se]) continue;
        int u = x.se;
        for(auto v : g[u]) {
            if(dist[v.fi] > dist[u] + v.se) {
                dist[v.fi] = dist[u] + v.se;
                q.insert({dist[v.fi], v.fi});
            }
        }
    }
    fr(i, 1, c) {
        if(ter[i]) {
            ans = min(ans, dist[i] + cost1[i]);
        }
    }
    if(ans == 1e18) ans = -1;
    cout << ans;
}

int main() {
	ios :: sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	// cin >> t;
	for(int tt = 1; tt <= t; tt++) {
		solve();
	}
	return 0;
}

Compiler output:
a.cc: In function 'void solve()':
a.cc:153:48: warning: narrowing conversion of 'cost[j]' from 'll' {aka 'long long int'} to 'int' [-Wnarrowing]
  153 |                     g[ii][0].pb({{i, 0}, cost[j]});
      |                                          ~~~~~~^
a.cc:161:48: warning: narrowing conversion of 'cost[j]' from 'll' {aka 'long long int'} to 'int' [-Wnarrowing]
  161 |                     g[ii][1].pb({{i, 0}, cost[j]});
      |                                          ~~~~~~^
a.cc:169:48: warning: narrowing conversion of 'cost[j]' from 'll' {aka 'long long int'} to 'int' [-Wnarrowing]
  169 |                     g[ii][1].pb({{i, 1}, cost[j]});
      |                                          ~~~~~~^
a.cc:177:48: warning: narrowing conversion of 'cost[j]' from 'll' {aka 'long long int'} to 'int' [-Wnarrowing]
  177 |                     g[ii][0].pb({{i, 0}, cost[j]});
      |                                          ~~~~~~^
a.cc:238:23: error: no match for 'operator[]' (operand types are 'll [4005][2]' {aka 'long long int [4005][2]'} and 'std::pair<int, int>')
  238 |         if(x.fi > dist[x.se]) continue;
      |                       ^
a.cc:20:12: error: cannot convert 'std::pair<int, int>' to 'int' in initialization
   20 | #define se second
      |            ^
      |            |
      |            std::pair<int, int>
a.cc:239:19: note: in expansion of macro 'se'
  239 |         int u = x.se;
      |                   ^~
a.cc:19:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'first'
   19 | #define fi first
      |            ^~~~~
a.cc:241:23: note: in expansion of macro 'fi'
  241 |             if(dist[v.fi] > dist[u] + v.se) {
      |                       ^~
a.cc:20:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'second'
   20 | #define se second
      |            ^~~~~~
a.cc:241:41: note: in expansion of macro 'se'
  241 |             if(dist[v.fi] > dist[u] + v.se) {
      |                                         ^~
a.cc:19:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'first'
   19 | #define fi first
      |            ^~~~~
a.cc:242:24: note: in expansion of macro 'fi'
  242 |                 dist[v.fi] = dist[u] + v.se;
      |                        ^~
a.cc:20:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'second'
   20 | #define se second
      |            ^~~~~~
a.cc:242:42: note: in expansion of macro 'se'
  242 |                 dist[v.fi] = dist[u] + v.se;
      |                                          ^~
a.cc:19:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'first'
   19 | #define fi first
      |            ^~~~~
a.cc:243:34: note: in expansion of macro 'fi'
  243 |                 q.insert({dist[v.fi], v.fi});
      |                                  ^~
a.cc:19:12: error: 'class std::vector<std::pair<std::pair<int, int>, int> >' has no member named 'first'
   19 | #define fi first
      |            ^~~~~
a.cc:243:41: note: in expansion of macro 'fi'
  243 |                 q.insert({dist[v.fi], v.fi});
      |                                         ^~
a.cc:243:25: error: no matching function for call to 'std::set<std::pair<long long int, std::pair<int, int> > >::insert(<brace-enclosed initializer list>)'
  243 |                 q.insert({dist[v.fi], v.fi});
      |                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/14/set:63,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:158,
                 from a.cc:8:
/usr/include/c++/14/bits/stl_set.h:568:9: note: candidate: 'template<class _InputIterator> void std::set<_Key, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _Key = std::pair<long long int, std::pair<int, int> >; _Compare = std::less<std::pair<long long int, std::pair<int, int> > >; _Alloc = std::allocator<std::pair<long long int, std::pair<int, int> > >]'
  568 |         insert(_InputIterator __first, _InputIterator __last)
      |         ^~~~~~
/usr/include/c++/14/bits/stl_set.h:568:9: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/14/bits/stl_set.h:511:7: note: candidate: 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::pair<long long int, std::pair<int, int> >; _Compare = std::less<std::pair<long long int, std::pair<int, int> > >; _Alloc = std::allocator<std::pair<long long int, std::pair<int, int> > >; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pair<long long int, std::pair<int, int> > >, std::allocator<std::pair<long long int, std::pair<int, int> > > >::const_iterator; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other = std::allocator<std::pair<long long int, std::pair<int, int> > >; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key> = __gnu_cxx::__alloc_traits<std::allocator<std::pair<long long int, std::pair<int, int> > >, std::pair<long long int, std::pair<int, int> > >::rebind<std::pair<long long int, std::pair<int, int> > >; typename _Alloc::value_type = std::pair<long long int, std::pair<int, int> >; value_type = std::pair<long long int, std::pair<int, int> >]'
  511 |       insert(const value_type& __x)
      |       ^~~~~~
/usr/include/c++/14/bits/stl_set.h:511:32: note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const std::set<std::pair<long long int, std::pair<int, int> > >::value_type&' {aka 'const std::pair<long long int, std::pair<int, int> >&'}
  511 |       insert(const value_type& __x)
      |              ~~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/14/bits/stl_set.h:520:7: note: candidate: 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(value_type&&) [with _Key = std::pair<long long int, std::pair<int, int> >; _Compare = std::less<std::pair<long long int, std::pair<int, int> > >; _Alloc = std::allocator<std::pair<long long int, std::pair<int, int> > >; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pair<long long int, std::pair<int, int> > >, std::allocator<std::pair<long long int, std::pair<int, int> > > >::const_iterator; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other = std::allocator<std::pair<long long int, std::pair<int, int> > >; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key> = __gnu_cxx::__alloc_traits<std::allocator<std::pair<long long int, std::pair<int, int> > >, std::pair<long long int, std::pair<int, int> > >::rebind<std::pair<long long int, std::pair<int, int> > >; typename _Alloc::value_type = std::pair<long long int, std::pair<int, int> >; value_type = std::pair<long long int, std::pair<int, int> >]'
  520 |       insert(value_type&& __x)
      |       ^~~~~~
/usr/include/c++/14/bits/stl_set.h:520:27: note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'std::set<std::pair<long long int, std::pair<int, int> > >::value_type&&' {aka 'std::pair<long long int, std::pair<int, int> >&&'}
  520 |       insert(value_type&& __x)
      |              ~~~~~~~~~~~~~^~~
/usr/include/c++/14/bits/stl_set.h:548:7: note: candidate: 'std::set<_Key, _Compare, _Alloc>::iterator std::set<_Key, _Compare, _Alloc>::insert(const_iterator, const value_type&) [with _Key = std::pair<long long int, std::pair<int, int> >; _Compare = std::less<std::pair<long long int, std::pair<int, int> > >; _Alloc = std::allocator<std::pair<long long int, std::pair<int, int> > >; iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pair<long long int, std::pair<int, int> > >, std::allocator<std::pair<long long int, std::pair<int, int> > > >::const_iterator; const_iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pair<long long int, std::pair<int, int> > >, std::allocator<std::pair<long long int, std::pair<int, int> > > >::const_iterator; value_type = std::pair<long long int, std::pair<int, int> >]'
  548 |       insert(const_iterator __position, const value_type& __x)
      |       ^~~~~~
/usr/include/c++/14/bits/stl_set.h:548:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/14/bits/stl_set.h:553:7: note: candidate: 'std::set<_Key, _Compare, _Alloc>::iterator std::set<_Key, _Compare, _Alloc>::insert(const_iterator, value_type&&) [with _Key = std::pair<long long int, std::pair<int, int> >; _Compare = std::less<std::pair<long long int, std::pair<int, int> > >; _Alloc = std::allocator<std::pair<long long int, std::pair<int, int> > >; iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pair<long long int, std::pair<int, int> > >, std::allocator<std::pair<long long int, std::pair<int, int> > > >::const_iterator; const_iterator = std::_Rb_tree<std::pair<long long int, std::pair<int, int> >, std::pair<long long int, std::pair<int, int> >, std::_Identity<std::pair<long long int, std::pair<int, int> > >, std::less<std::pai