Problem p02587 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define SZ(a) (int)(a).size()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define make_unique(a)                                                         \\
  sort(all((a))), (a).resize(unique(all((a))) - (a).begin())

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;
typedef double DD;
typedef long double LD;
typedef pair<LL, LL> PLL;
typedef pair<DD, DD> PDD;
typedef vector<int> VI;
typedef vector<LL> VL;

const int N = 52, L = 44;
struct A {
  LL cost;
  int st, idx;
  bool operator<(const A &o) const { return cost > o.cost; }
};
vector<A> g[2][N * L];
vector<string> dict, word;
LL dp[2][N * L], cost[N];
int search(string x) { return lower_bound(all(dict), x) - dict.begin(); }
void solve() {
  int n;
  cin >> n;
  word.resize(n + 1);
  FOR(i, 1, n) {
    cin >> word[i] >> cost[i];
    int l = word[i].length();
    FOR(j, 0, l - 1) {
      dict.pb(word[i].substr(0, j + 1));
      dict.pb(word[i].substr(j));
    }
  }
  dict.pb("");
  make_unique(dict);
  LL inf = 1e18;
  int m = SZ(dict);
  FOR(i, 0, m - 1) {
    // printf("%d : %s\\n",i,dict[i].c_str());
    dp[0][i] = dp[1][i] = inf;
    int l = dict[i].length();
    // check if itself is palindrome
    bool chek = true;
    FOR(j, 0, l / 2 - 1) {
      if (dict[i][j] != dict[i][l - 1 - j]) {
        chek = false;
        break;
      }
    }
    if (chek) {
      // this is already palindrome
      // cout << "kono palindrome da!" << endl;
      dp[0][i] = dp[1][i] = 0;
      continue;
    }
    // adding suffix
    FOR(j, 1, n) {
      bool ch = true;
      int ll = word[j].length();
      FOR(k, 0, min(l - 1, ll - 1)) {
        if (dict[i][k] != word[j][ll - 1 - k]) {
          ch = false;
          break;
        }
      }
      if (!ch)
        continue;
      if (l == ll)
        g[0][0].pb({cost[j], 0, i});
      if (l < ll) {
        int idx = search(word[j].substr(0, ll - l));
        g[1][idx].pb({cost[j], 0, i});
      }
      if (l > ll) {
        int idx = search(dict[i].substr(ll));
        g[0][idx].pb({cost[j], 0, i});
      }
    }
    // adding prefix
    FOR(j, 1, n) {
      bool ch = true;
      int ll = word[j].length();
      FOR(k, 0, min(l - 1, ll - 1)) {
        if (word[j][k] != dict[i][l - 1 - k]) {
          ch = false;
          break;
        }
      }
      if (!ch)
        continue;
      if (l == ll)
        g[0][0].pb({cost[j], 1, i});
      if (ll < l) {
        int idx = search(dict[i].substr(0, l - ll));
        g[1][idx].pb({cost[j], 1, i});
      }
      if (ll > l) {
        int idx = search(word[j].substr(l));
        g[0][idx].pb({cost[j], 1, i});
      }
    }
  }
  // dijk
  priority_queue<A> dijk;
  FOR(i, 0, m - 1) {
    FOR(j, 0, 1) {
      if (dp[j][i] != inf) {
        dijk.push({dp[j][i], j, i});
      }
    }
  }
  while (!dijk.empty()) {
    LL cost = dijk.top().cost;
    int st = dijk.top().st;
    int idx = dijk.top().idx;
    dijk.pop();
    if (cost != dp[st][idx])
      continue;
    for (A e : g[st][idx]) {
      if (dp[e.st][e.idx] > cost + e.cost) {
        dp[e.st][e.idx] = cost + e.cost;
        dijk.push({dp[e.st][e.idx], e.st, e.idx});
      }
    }
  }
  // brute
  LL ans = inf;
  bool found = false;
  FOR(i, 1, n) {
    int idx = search(word[i]);
    FOR(j, 0, 1) {
      if (dp[j][idx] != inf) {
        found = true;
        ans = min(ans, dp[j][idx] + cost[i]);
      }
    }
  }
  if (found)
    cout << ans;
  else
    cout << -1;
}

int main() {
  solve();
  return 0;
}
/*
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

Error: WA

Fixed submission:

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define SZ(a) (int)(a).size()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define make_unique(a)                                                         \\
  sort(all((a))), (a).resize(unique(all((a))) - (a).begin())

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;
typedef double DD;
typedef long double LD;
typedef pair<LL, LL> PLL;
typedef pair<DD, DD> PDD;
typedef vector<int> VI;
typedef vector<LL> VL;

const int N = 52, L = 22;
struct A {
  LL cost;
  int st, idx;
  bool operator<(const A &o) const { return cost > o.cost; }
};
vector<A> g[2][N * L];
vector<string> dict, word;
LL dp[2][N * L], cost[N];
int search(string x) { return lower_bound(all(dict), x) - dict.begin(); }
void solve() {
  int n;
  cin >> n;
  word.resize(n + 1);
  FOR(i, 1, n) {
    cin >> word[i] >> cost[i];
    int l = word[i].length();
    FOR(j, 0, l - 1) {
      dict.pb(word[i].substr(0, j + 1));
      dict.pb(word[i].substr(j));
    }
  }
  dict.pb("");
  make_unique(dict);
  LL inf = 1e18;
  int m = SZ(dict);
  FOR(i, 0, m - 1) {
    // printf("%d : %s\\n",i,dict[i].c_str());
    dp[0][i] = dp[1][i] = inf;
    int l = dict[i].length();
    // check if itself is palindrome
    bool chek = true;
    FOR(j, 0, l / 2 - 1) {
      if (dict[i][j] != dict[i][l - 1 - j]) {
        chek = false;
        break;
      }
    }
    if (chek) {
      // this is already palindrome
      // cout << "kono palindrome da!" << endl;
      dp[0][i] = dp[1][i] = 0;
      continue;
    }
    // adding suffix
    FOR(j, 1, n) {
      bool ch = true;
      int ll = word[j].length();
      FOR(k, 0, min(l - 1, ll - 1)) {
        if (dict[i][k] != word[j][ll - 1 - k]) {
          ch = false;
          break;
        }
      }
      if (!ch)
        continue;
      if (l == ll)
        g[0][0].pb({cost[j], 0, i});
      if (l < ll) {
        int idx = search(word[j].substr(0, ll - l));
        g[1][idx].pb({cost[j], 0, i});
      }
      if (l > ll) {
        int idx = search(dict[i].substr(ll));
        g[0][idx].pb({cost[j], 0, i});
      }
    }
    // adding prefix
    FOR(j, 1, n) {
      bool ch = true;
      int ll = word[j].length();
      FOR(k, 0, min(l - 1, ll - 1)) {
        if (word[j][k] != dict[i][l - 1 - k]) {
          ch = false;
          break;
        }
      }
      if (!ch)
        continue;
      if (l == ll)
        g[0][0].pb({cost[j], 1, i});
      if (ll < l) {
        int idx = search(dict[i].substr(0, l - ll));
        g[1][idx].pb({cost[j], 1, i});
      }
      if (ll > l) {
        int idx = search(word[j].substr(l));
        g[0][idx].pb({cost[j], 0, i});
      }
    }
  }
  // dijk
  priority_queue<A> dijk;
  FOR(i, 0, m - 1) {
    FOR(j, 0, 1) {
      if (dp[j][i] != inf) {
        dijk.push({dp[j][i], j, i});
      }
    }
  }
  while (!dijk.empty()) {
    LL cost = dijk.top().cost;
    int st = dijk.top().st;
    int idx = dijk.top().idx;
    dijk.pop();
    if (cost != dp[st][idx])
      continue;
    for (A e : g[st][idx]) {
      if (dp[e.st][e.idx] > cost + e.cost) {
        dp[e.st][e.idx] = cost + e.cost;
        dijk.push({dp[e.st][e.idx], e.st, e.idx});
      }
    }
  }
  // brute
  LL ans = inf;
  bool found = false;
  FOR(i, 1, n) {
    int idx = search(word[i]);
    FOR(j, 0, 1) {
      if (dp[j][idx] != inf) {
        found = true;
        ans = min(ans, dp[j][idx] + cost[i]);
      }
    }
  }
  if (found)
    cout << ans;
  else
    cout << -1;
}

int main() {
  solve();
  return 0;
}
/*
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */