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

#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
} // namespace IO

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());
  else
    reverse(u.begin(), u.end());
  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)) {
    if (res == "") {
      puts("!!!!");
      cout << flg << "\\n" << u << "\\n" << v << endl;
      puts("!!!!");
    }
  }
  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 = str[i][j] + cur;
      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;
  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;
}

Error: 0

Fixed submission:

#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
} // namespace IO

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());
  else
    reverse(u.begin(), u.end());
  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;
  }
  assert(str_to_id.count(res));
  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;
  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;
}