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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 40
#define MAX_LEN 250

void strcpy(char *to, char *str) {
  to[0] = '\\0';
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

void strcpy2(char to[300], const char str[300]) {
  to[0] = '\\0';
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

void addcpy(char to[300], const char str[300]) {
  int index, second_index;
  for (index = 0; to[index] != '\\0'; index++)
    ;
  // printf("index:%d\\n",index);
  for (second_index = 0; str[second_index] != '\\0'; second_index++) {
    to[index + second_index] = str[second_index];
  }
  to[index + second_index] = '\\0';
}

bool strCmp(const char base[300], const char comp[300]) {
  int length1, length2;
  for (length1 = 0; base[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; comp[length2] != '\\0'; length2++)
    ;
  if (length1 != length2)
    return false;

  for (int i = 0; base[i] != '\\0'; i++) {
    if (base[i] != comp[i])
      return false;
  }
  return true;
}

// 辞書順が等しい時は3,leftの方が早い場合は1,rightの方が早いときは2
int strCmp2(const char left[300], const char right[300]) {
  int i;

  if (strCmp(left, right))
    return 3;

  for (i = 0; left[i] != '\\0' && right[i] != '\\0'; i++) {
    if (left[i] != right[i]) {
      if (left[i] < right[i])
        return 1;
      else {
        return 2;
      }
    }
  }
  if (left[i] == '\\0')
    return 1;
  else {
    return 2;
  }
}

struct Edge {
  Edge(int arg_to, char arg_buf[7]) {
    to = arg_to;
    strcpy(buf, arg_buf);
    deleted = false;
  }
  int to;
  char buf[7];
  bool deleted;
};

struct Data {
  Data(int arg_node_id, int arg_edge_id) {
    node_id = arg_node_id;
    edge_id = arg_edge_id;
  }
  int node_id;
  int edge_id;
};

struct Info {
  Info(int arg_node_id, char arg_tmp_string[300]) {
    node_id = arg_node_id;
    strcpy(tmp_string, arg_tmp_string);
  }

  Info() { node_id = 0; }

  bool operator<(const struct Info &arg) const {
    int compare = strCmp2(tmp_string, arg.tmp_string);

    if (compare == 2 || compare == 3) { // argの方が早い
      return true;                      // PQなので逆
    } else {
      return false;
    }
  }
  int node_id;
  char tmp_string[300];
};

int N, E, start, goal;
char min_string[40][251][300]; // min_string[node_id][length][string]
bool reachable[NUM][NUM];
vector<Edge> G[NUM];

void func() {

  for (int i = 0; i < N; i++)
    G[i].clear();

  int from, to;
  char buf[7];

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < N; k++) {
      if (i != k) {
        reachable[i][k] = false;
      } else {
        reachable[i][k] = true;
      }
    }
  }

  for (int i = 0; i < E; i++) {
    scanf("%d %d %s", &from, &to, buf);
    reachable[from][to] = true;
    G[from].push_back(Edge(to, buf));
  }

  for (int mid = 0; mid < N; mid++) {
    for (int st = 0; st < N; st++) {
      if (!reachable[st][mid])
        continue;
      for (int gl = 0; gl < N; gl++) {
        if (!reachable[mid][gl])
          continue;
        reachable[st][gl] = true;
      }
    }
  }

  if (!reachable[start][goal]) {
    printf("NO\\n");
    return;
  }

  int compare;

  // エッジを削る(同じノードかつ同じ行先)
  /*for(int i = 0; i < N; i++){
      for(int k = 0; k+1 < G[i].size(); k++){
          if(G[i][k].deleted)continue;
          for(int p = k+1; p < G[i].size(); p++){
              if(G[i][k].to != G[i][p].to)continue;
              if(G[i][k].buf[0] == G[i][p].buf[0])continue;
  //片方がもう片方に含まれる場合はSKIP

              compare = strCmp2(G[i][k].buf,G[i][p].buf);

              if(compare == 1){
                  G[i][p].deleted = true;
              }else{
                  G[i][k].deleted = true;
              }
          }
      }
  }*/

  // bool check[N];

  // 長い文字列を記録
  for (int i = 0; i < N; i++) {
    // check[i] = false; //閉路に属しているか
    for (int length = 0; length < MAX_LEN; length++) {
      for (int k = 0; k <= length; k++) {
        min_string[i][length][k] = 'z';
      }
      min_string[i][length][length + 1] = '\\0';
    }
  }

  min_string[start][0][0] = '\\0';

  priority_queue<Info> Q;
  char first_string[300];
  first_string[0] = '\\0';

  Q.push(Info(start, first_string));
  int next_node, next_length;
  char ans[300], work[300];

  // int debug = 0;

  int length;

  while (!Q.empty()) {

    for (length = 0; Q.top().tmp_string[length] != '\\0'; length++)
      ;

    if (length >= 6 * N) {
      printf("NO\\n");
      return;
    }

    if (Q.top().node_id == goal) {

      printf("%s\\n", Q.top().tmp_string);
      return;
    } else if (strCmp2(Q.top().tmp_string,
                       min_string[Q.top().node_id][length]) == 2) {
      Q.pop();
    } else {

      for (int i = 0; i < G[Q.top().node_id].size(); i++) {
        // if(G[Q.top().node_id][i].deleted)continue;
        next_node = G[Q.top().node_id][i].to;
        // if(next_node == Q.top().node_id || reachable[next_node][goal] ==
        // false)continue; //自己ループ&ゴールに着けないノードは無視
        if (reachable[next_node][goal] == false)
          continue;

        // 新しい文字列を作る
        work[0] = '\\0';
        strcpy2(work, Q.top().tmp_string);
        // printf("work:%s tmp_str:%s\\n",work,Q.top().tmp_string);
        addcpy(work, G[Q.top().node_id][i].buf);
        // printf("work:%s buf:%s\\n",work,G[Q.top().node_id][i].buf);

        for (next_length = 0; work[next_length] != '\\0'; next_length++)
          ;

        if (strCmp2(work, min_string[next_node][next_length]) != 1)
          continue;
        /* if(next_node == goal){
                 printf("%s\\n",work);
                 return;
         }*/

        strcpy2(min_string[next_node][next_length], work);

        Info next_info;
        next_info.node_id = next_node;
        strcpy(next_info.tmp_string, work);

        Q.push(next_info);
      }
      Q.pop();
    }
  }

  printf("NO\\n");
  return;
}

int main() {

  while (true) {
    scanf("%d %d %d %d", &N, &E, &start, &goal);
    if (N == 0 && E == 0 && start == 0 && goal == 0)
      break;

    func();
  }

  return 0;
}


Error: WA

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 40
#define MAX_LEN 250

void strcpy(char *to, char *str) {
  to[0] = '\\0';
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

void strcpy2(char to[300], const char str[300]) {
  to[0] = '\\0';
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

void addcpy(char to[300], const char str[300]) {
  int index, second_index;
  for (index = 0; to[index] != '\\0'; index++)
    ;
  for (second_index = 0; str[second_index] != '\\0'; second_index++) {
    to[index + second_index] = str[second_index];
  }
  to[index + second_index] = '\\0';
}

bool strCmp(const char base[300], const char comp[300]) {
  int length1, length2;
  for (length1 = 0; base[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; comp[length2] != '\\0'; length2++)
    ;
  if (length1 != length2)
    return false;

  for (int i = 0; base[i] != '\\0'; i++) {
    if (base[i] != comp[i])
      return false;
  }
  return true;
}

// 辞書順が等しい時は3,leftの方が早い場合は1,rightの方が早いときは2
int strCmp2(const char left[300], const char right[300]) {
  int i;

  if (strCmp(left, right))
    return 3;

  for (i = 0; left[i] != '\\0' && right[i] != '\\0'; i++) {
    if (left[i] != right[i]) {
      if (left[i] < right[i])
        return 1;
      else {
        return 2;
      }
    }
  }
  // rightがleftを含む
  if (left[i] == '\\0')
    return 4;
  else {
    return 5; // leftがrightを含む
  }
}

struct Edge {
  Edge(int arg_to, char arg_buf[300]) {
    to = arg_to;
    strcpy(buf, arg_buf);
    deleted = false;
  }
  bool operator<(const struct Edge &arg) const {
    int compare = strCmp2(buf, arg.buf);

    if (compare == 2 || compare == 3) {
      return false;
    } else {
      return true;
    }
  }
  int to;
  char buf[300];
  bool deleted;
};

struct Data {
  Data(int arg_node_id, int arg_edge_id) {
    node_id = arg_node_id;
    edge_id = arg_edge_id;
  }
  int node_id;
  int edge_id;
};

struct Info {
  Info(int arg_node_id, char arg_tmp_string[300]) {
    node_id = arg_node_id;
    strcpy(tmp_string, arg_tmp_string);
  }

  Info() { node_id = 0; }

  bool operator<(const struct Info &arg) const {
    int compare = strCmp2(tmp_string, arg.tmp_string);

    if (compare == 2 || compare == 3) {
      return true;
    } else {
      return false;
    }
  }
  int node_id;
  char tmp_string[300];
  bool visited[NUM];
};

int N, E, start, goal;
char min_prefix[40][300], min_string[40][251][300];
bool reachable[NUM][NUM];
vector<Edge> G[NUM];

void func() {

  for (int i = 0; i < N; i++)
    G[i].clear();

  int from, to;
  char buf[300];

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < N; k++) {
      if (i != k) {
        reachable[i][k] = false;
      } else {
        reachable[i][k] = true;
      }
    }
  }

  for (int i = 0; i < E; i++) {
    scanf("%d %d %s", &from, &to, buf);
    reachable[from][to] = true;
    G[from].push_back(Edge(to, buf));
  }

  for (int mid = 0; mid < N; mid++) {
    for (int st = 0; st < N; st++) {
      if (!reachable[st][mid])
        continue;
      for (int gl = 0; gl < N; gl++) {
        if (!reachable[mid][gl])
          continue;
        reachable[st][gl] = true;
      }
    }
  }

  if (!reachable[start][goal]) {
    printf("NO\\n");
    return;
  }

  for (int i = 0; i < N; i++) {
    sort(G[i].begin(), G[i].end());

    for (int k = 0; k < 250; k++) {
      min_prefix[i][k] = 'z';
    }
    min_prefix[i][250] = '\\0';

    for (int length = 0; length < MAX_LEN; length++) {
      for (int k = 0; k <= length; k++) {
        min_string[i][length][k] = 'z';
      }
      min_string[i][length][length + 1] = '\\0';
    }
  }

  min_string[start][0][0] = '\\0';
  min_prefix[0][0] = '\\0';

  priority_queue<Info> Q;
  char first_string[300];
  first_string[0] = '\\0';

  Info first;
  strcpy(first.tmp_string, first_string);
  first.node_id = start;
  for (int i = 0; i < N; i++)
    first.visited[i] = false;
  first.visited[start] = true;

  Q.push(first);
  int next_node, next_length;
  char work[300];

  int length;

  while (!Q.empty()) {

    for (length = 0; Q.top().tmp_string[length] != '\\0'; length++)
      ;

    if (length >= 6 * N) {
      printf("NO\\n");
      return;
    }

    // printf("node:%d %s\\n",Q.top().node_id,Q.top().tmp_string);

    if (Q.top().node_id == goal) {

      printf("%s\\n", Q.top().tmp_string);
      return;
    } else if (strCmp2(Q.top().tmp_string,
                       min_string[Q.top().node_id][length]) == 2) {
      Q.pop();
    } else {

      for (int i = 0; i < G[Q.top().node_id].size(); i++) {
        next_node = G[Q.top().node_id][i].to;
        if (reachable[next_node][goal] == false)
          continue;

        // printf("next_node:%d\\n",next_node);

        work[0] = '\\0';
        strcpy2(work, Q.top().tmp_string);
        addcpy(work, G[Q.top().node_id][i].buf);

        for (next_length = 0; work[next_length] != '\\0'; next_length++)
          ;

        if (strCmp2(work, min_prefix[next_node]) == 2 ||
            strCmp2(work, min_prefix[next_node]) == 3)
          continue;

        switch (strCmp2(work, min_prefix[next_node])) {
        case 1: // 過去最少
        case 4: // pre_fixがworkを含む場合
          strcpy2(min_prefix[next_node], work);
          strcpy2(min_string[next_node][next_length], work);
          break;
        case 5: // workがpre_fixを含む場合
          /*if(Q.top().visited[next_node]){
                  //printf("prefix:%s
          next_node:%d\\n",min_prefix[next_node],next_node); printf("NO\\n");
          //最小ループ return;
          }*/
          strcpy2(min_string[next_node][next_length], work);
          break;
        }

        if (next_node == goal) {
          printf("%s\\n", work);
          return;
        }

        Info next_info;
        next_info.node_id = next_node;
        strcpy(next_info.tmp_string, work);
        for (int k = 0; k < N; k++)
          next_info.visited[k] = Q.top().visited[k];
        next_info.visited[next_node] = true;

        Q.push(next_info);
      }
      Q.pop();
    }
  }

  printf("NO\\n");
  return;
}

int main() {

  while (true) {
    scanf("%d %d %d %d", &N, &E, &start, &goal);
    if (N == 0 && E == 0 && start == 0 && goal == 0)
      break;

    func();
  }

  return 0;
}