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

#define LL long long int
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

char S[55][25];
LL C[55];

int nodeCount;
map<string, int> pre_str2NodeID;
map<string, int> suf_str2NodeID;
string nodeID2Str[2100];
bool Palindrome[2100];
LL Distance[2100];
bool Visit[2100];
int PRE_COUNT;
int N;

struct nextNode {
  int ne;
  LL weight;
  nextNode(int _n, LL _w) : ne(_n), weight(_w) {}
};

vector<nextNode> weight[2100];

int main() {
  N = 0;
  nodeCount = 1;
  scanf("%d", &N);
  for (int i = 0; i < N; ++i) {
    scanf("%s%lld", S[i], &C[i]);
  }

  pre_str2NodeID.clear();
  suf_str2NodeID.clear();

  Palindrome[0] = false;
  nodeID2Str[0] = "";
  for (int i = 0; i < N; ++i) { // make node, prefix
    int sl = strlen(S[i]);
    string str = S[i];
    for (int k = 0; k <= sl; ++k) {
      string pre = str.substr(sl - k, k);
      if (pre_str2NodeID.count(pre) == 0) {
        string preR = pre;
        reverse(preR.begin(), preR.end());
        if (pre.compare(preR) == 0 || pre.length() == 0) {
          Palindrome[nodeCount] = true;
        } else
          Palindrome[nodeCount] = false;
        nodeID2Str[nodeCount] = pre;
        pre_str2NodeID[pre] = nodeCount++;
        // cout << "[Trace] pre_str2NodeID[" << pre << "] =  " << nodeCount-1 <<
        // endl; cout << "[Trace] Palindrome[" << nodeCount-1 << "] =  " <<
        // Palindrome[nodeCount-1] << endl;
      }
    }
  }

  PRE_COUNT = nodeCount;

  for (int i = 0; i < N; ++i) { // make node, suffix
    int sl = strlen(S[i]);
    string str = S[i];
    for (int k = 0; k <= sl; ++k) {
      string suf = str.substr(0, k);
      if (suf_str2NodeID.count(suf) == 0) {
        string sufR = suf;
        reverse(sufR.begin(), sufR.end());
        if (suf.compare(sufR) == 0 || suf.length() == 0) {
          Palindrome[nodeCount] = true;
        } else
          Palindrome[nodeCount] = false;
        nodeID2Str[nodeCount] = suf;
        suf_str2NodeID[suf] = nodeCount++;
        // cout << "[Trace] suf_str2NodeID[" << suf << "] =  " << nodeCount-1 <<
        // endl; cout << "[Trace] Palindrome[" << nodeCount-1 << "] =  " <<
        // Palindrome[nodeCount-1] << endl;
      }
    }
  }

  for (int i = 0; i < N; ++i) {
    string str = S[i];
    string strR = str;
    reverse(strR.begin(), strR.end());

    weight[0].push_back(nextNode(pre_str2NodeID[str], C[i]));
    weight[0].push_back(nextNode(suf_str2NodeID[str], C[i]));

    for (int j = 1; j < PRE_COUNT; ++j) {
      string state = nodeID2Str[j];
      if (state.length() >= strR.length()) {
        auto miss = mismatch(strR.begin(), strR.end(), state.begin());
        if (miss.first == strR.end()) {
          string suf =
              state.substr(strR.length(), state.length() - strR.length());
          weight[j].push_back(nextNode(pre_str2NodeID[suf], C[i]));
        }
      } else {
        auto miss = mismatch(state.begin(), state.end(), strR.begin());
        if (miss.first == state.end()) {
          string suf =
              strR.substr(state.length(), strR.length() - state.length());
          reverse(suf.begin(), suf.end());
          weight[j].push_back(nextNode(suf_str2NodeID[suf], C[i]));
        }
      }
    }

    for (int j = PRE_COUNT; j < nodeCount; ++j) {
      string state = nodeID2Str[j];
      reverse(state.begin(), state.end());
      if (state.length() >= str.length()) {
        auto miss = mismatch(str.begin(), str.end(), state.begin());
        if (miss.first == str.end()) {
          string suf =
              state.substr(str.length(), state.length() - str.length());
          reverse(suf.begin(), suf.end());
          weight[j].push_back(nextNode(suf_str2NodeID[suf], C[i]));
        }
      } else {
        auto miss = mismatch(state.begin(), state.end(), str.begin());
        if (miss.first == state.end()) {
          string suf =
              str.substr(state.length(), str.length() - state.length());
          // cout<<"[Debug] suf: "<<suf<<endl;
          weight[j].push_back(nextNode(pre_str2NodeID[suf], C[i]));
        }
      }
    }
  }

  // shortest distance
  Distance[0] = 0;
  Visit[0] = false;

  for (int i = 1; i < nodeCount; ++i) {
    Distance[i] = -1;
    Visit[i] = false;
  }

  for (int i = 0; i < nodeCount; ++i) {
    int nowClosest = -1;
    for (int j = 0; j < nodeCount; ++j) {
      // cout<<"[Trace] Distance[" << j << "] = " << Distance[j] << endl;
      if (!Visit[j] && Distance[j] >= 0 &&
          (nowClosest == -1 || Distance[j] < Distance[nowClosest])) {
        nowClosest = j;
      }
    }
    if (nowClosest == -1)
      break;
    // printf("[Trace] nowClosest = %d\\n", nowClosest);
    Visit[nowClosest] = true;
    for (auto it = weight[nowClosest].begin(); it != weight[nowClosest].end();
         ++it) {
      if (Distance[it->ne] == -1 ||
          Distance[it->ne] > Distance[nowClosest] + it->weight) {
        Distance[it->ne] = Distance[nowClosest] + it->weight;
      }
    }
  }

  LL bestResult = -1;

  for (int i = 0; i < nodeCount; ++i) {
    if (Palindrome[i] && (bestResult == -1 || Distance[i] < bestResult) &&
        Distance[i] > 0)
      bestResult = Distance[i];
  }

  printf("%lld\\n", bestResult);
}

Error: WA

Fixed submission:

#define LL long long int
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

char S[55][25];
LL C[25];

int nodeCount;
map<string, int> pre_str2NodeID;
map<string, int> suf_str2NodeID;
string nodeID2Str[2100];
bool Palindrome[2100];
LL Distance[2100];
bool Visit[2100];
int PRE_COUNT;
int N;

struct nextNode {
  int ne;
  int weight;
  nextNode(int _n, int _w) : ne(_n), weight(_w) {}
};

vector<nextNode> weight[2100];

int main() {
  N = 0;
  nodeCount = 1;
  scanf("%d", &N);
  for (int i = 0; i < N; ++i) {
    scanf("%s%lld", S[i], &C[i]);
  }

  pre_str2NodeID.clear();
  suf_str2NodeID.clear();

  Palindrome[0] = false;
  nodeID2Str[0] = "";
  for (int i = 0; i < N; ++i) { // make node, prefix
    int sl = strlen(S[i]);
    string str = S[i];
    for (int k = 0; k <= sl; ++k) {
      string pre = str.substr(sl - k, k);
      if (pre_str2NodeID.count(pre) == 0) {
        string preR = pre;
        reverse(preR.begin(), preR.end());
        if (pre.compare(preR) == 0) {
          Palindrome[nodeCount] = true;
        } else
          Palindrome[nodeCount] = false;
        nodeID2Str[nodeCount] = pre;
        pre_str2NodeID[pre] = nodeCount++;
        // cout << "[Trace] pre_str2NodeID[" << pre << "] =  " << nodeCount-1 <<
        // endl; cout << "[Trace] Palindrome[" << nodeCount-1 << "] =  " <<
        // Palindrome[nodeCount-1] << endl;
      }
    }
  }

  PRE_COUNT = nodeCount;

  for (int i = 0; i < N; ++i) { // make node, suffix
    int sl = strlen(S[i]);
    string str = S[i];
    for (int k = 0; k <= sl; ++k) {
      string suf = str.substr(0, k);
      if (suf_str2NodeID.count(suf) == 0) {
        string sufR = suf;
        reverse(sufR.begin(), sufR.end());
        if (suf.compare(sufR) == 0) {
          Palindrome[nodeCount] = true;
        } else
          Palindrome[nodeCount] = false;
        nodeID2Str[nodeCount] = suf;
        suf_str2NodeID[suf] = nodeCount++;
        // cout << "[Trace] suf_str2NodeID[" << suf << "] =  " << nodeCount-1 <<
        // endl; cout << "[Trace] Palindrome[" << nodeCount-1 << "] =  " <<
        // Palindrome[nodeCount-1] << endl;
      }
    }
  }
  cout << nodeCount << endl;
  return 0;

  // for(int i = 0; i < N; ++i){ // make edge
  //     int sl = strlen(S[i]);
  //     string str = S[i];

  //     weight[0].push_back(nextNode(pre_str2NodeID[str], C[i]));
  //     weight[0].push_back(nextNode(suf_str2NodeID[str], C[i]));

  //     for(int k = 0; k <= sl; ++k){
  //         string pre = str.substr(0, k);
  //         string suf = str.substr(sl - k, k);
  //         // match pre => make new suf
  //         weight[pre_str2NodeID[pre]].push_back(nextNode(suf_str2NodeID[suf],
  //         C[i]));
  //         // match suf => make new pre
  //         weight[suf_str2NodeID[suf]].push_back(nextNode(pre_str2NodeID[pre],
  //         C[i]));
  //     }
  // }

  for (int i = 0; i < N; ++i) {
    string str = S[i];
    string strR = str;
    reverse(strR.begin(), strR.end());

    weight[0].push_back(nextNode(pre_str2NodeID[str], C[i]));
    weight[0].push_back(nextNode(suf_str2NodeID[str], C[i]));

    for (int j = 1; j < PRE_COUNT; ++j) {
      string state = nodeID2Str[j];
      if (state.length() >= strR.length()) {
        auto miss = mismatch(strR.begin(), strR.end(), state.begin());
        if (miss.first == strR.end()) {
          string suf =
              state.substr(strR.length(), state.length() - strR.length());
          weight[j].push_back(nextNode(pre_str2NodeID[suf], C[i]));
        }
      } else {
        auto miss = mismatch(state.begin(), state.end(), strR.begin());
        if (miss.first == state.end()) {
          string suf =
              str.substr(state.length(), strR.length() - state.length());
          reverse(suf.begin(), suf.end());
          weight[j].push_back(nextNode(suf_str2NodeID[suf], C[i]));
        }
      }
    }

    for (int j = PRE_COUNT; j < nodeCount; ++j) {
      string state = nodeID2Str[j];
      reverse(state.begin(), state.end());
      if (state.length() >= str.length()) {
        auto miss = mismatch(str.begin(), str.end(), state.begin());
        if (miss.first == str.end()) {
          string suf =
              state.substr(str.length(), state.length() - str.length());
          reverse(suf.begin(), suf.end());
          weight[j].push_back(nextNode(suf_str2NodeID[suf], C[i]));
        }
      } else {
        auto miss = mismatch(state.begin(), state.end(), str.begin());
        if (miss.first == state.end()) {
          string suf =
              str.substr(state.length(), str.length() - state.length());
          // cout<<"[Debug] suf: "<<suf<<endl;
          weight[j].push_back(nextNode(pre_str2NodeID[suf], C[i]));
        }
      }
    }
  }

  // shortest distance
  Distance[0] = 0;
  Visit[0] = false;

  for (int i = 1; i < nodeCount; ++i) {
    Distance[i] = -1;
    Visit[i] = false;
  }

  for (int i = 0; i < nodeCount; ++i) {
    int nowClosest = -1;
    for (int j = 0; j < nodeCount; ++j) {
      // cout<<"[Trace] Distance[" << j << "] = " << Distance[j] << endl;
      if (!Visit[j] && Distance[j] >= 0 &&
          (nowClosest == -1 || Distance[j] < Distance[nowClosest])) {
        nowClosest = j;
      }
    }
    if (nowClosest == -1)
      break;
    // printf("[Trace] nowClosest = %d\\n", nowClosest);
    Visit[nowClosest] = true;
    for (auto it = weight[nowClosest].begin(); it != weight[nowClosest].end();
         ++it) {
      if (Distance[it->ne] == -1 ||
          Distance[it->ne] > Distance[nowClosest] + it->weight) {
        Distance[it->ne] = Distance[nowClosest] + it->weight;
      }
    }
  }

  LL bestResult = -1;

  for (int i = 0; i < nodeCount; ++i) {
    if (Palindrome[i] &&
        (bestResult == -1 || Distance[i] < bestResult && Distance[i] > 0))
      bestResult = Distance[i];
  }

  printf("%lld\\n", bestResult);
}