Problem p00750 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;

class P {
public:
  string word;
  int edge;
  P(string a, int b) {
    word = a;
    edge = b;
  }
  bool operator<(const P &a) const { return word > a.word; }
};

int main() {
  int n, a, s, g;
  int from[400], to[400];
  string spell[400];
  string ans[250][40];
  bool use[250][40];
  int prvx[250][40], prvy[250][40];

  while (1) {
    cin >> n >> a >> s >> g;
    if (!n && !a && !s && !g)
      break;

    for (int i = 0; i < a; i++)
      cin >> from[i] >> to[i] >> spell[i];
    for (int i = 0; i < 250; i++) {
      for (int j = 0; j < n; j++) {
        ans[i][j] = "NO";
        prvx[i][j] = -1;
        prvy[i][j] = -1;
        use[i][j] = false;
      }
    }
    ans[0][s] = "";
    use[0][s] = true;

    priority_queue<P> str;
    for (int i = 0; i < a; i++) {
      if (from[i] == s)
        str.push(P(spell[i], i));
    }
    bool f = false;
    while (str.size()) {
      P hoge = str.top();
      string tmp = hoge.word;
      int num = hoge.edge;

      if (!use[tmp.size()][to[num]]) {
        ans[tmp.size()][to[num]] = tmp;
        prvx[tmp.size()][to[num]] = tmp.size() - spell[num].size();
        prvy[tmp.size()][to[num]] = from[num];
        use[tmp.size()][to[num]] = true;
        if (to[num] == g)
          break;
        for (int i = 0; i < a; i++) {
          int sum = tmp.size() + spell[i].size();
          if (from[i] == to[num] && sum < 250 && !use[sum][to[i]])
            str.push(P(tmp + spell[i], i));
        }
      }
      str.pop();
    }

    if (f)
      cout << "NO" << endl;
    else {
      string res = "NO";
      int posx = -1, posy = -1;
      for (int i = 0; i < 250; i++) {
        if (res == "NO") {
          res = ans[i][g];
          posx = i;
          posy = g;
        } else if (ans[i][g] != "NO" && res > ans[i][g]) {
          res = ans[i][g];
          posx = i;
          posy = g;
        }
      }

      if (posx >= 0) {
        vector<int> visit;
        int x = posx, y = posy;
        bool loop = false;
        visit.push_back(y);
        while (x >= 0 && y >= 0) {
          int t = prvx[x][y];
          y = prvy[x][y];
          x = t;

          for (int i = 0; i < (int)visit.size(); i++) {
            ;
            if (visit[i] == y)
              loop = true;
          }
          if (loop)
            break;
          visit.push_back(y);
        }
        if (loop)
          res = "NO";
      }
      cout << res << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

int main() {
  int n, a, s, g;
  int from[400], to[400];
  string spell[400];
  string ans[250][40];
  bool use[250][40];
  int prvx[250][40], prvy[250][40];

  while (1) {
    cin >> n >> a >> s >> g;
    if (!n && !a && !s && !g)
      break;

    for (int i = 0; i < a; i++)
      cin >> from[i] >> to[i] >> spell[i];
    for (int i = 0; i < 250; i++) {
      for (int j = 0; j < n; j++) {
        ans[i][j] = "NO";
        prvx[i][j] = -1;
        prvy[i][j] = -1;
        use[i][j] = false;
      }
    }
    ans[0][s] = "";
    use[0][s] = true;

    vector<pair<string, int>> str;
    for (int i = 0; i < a; i++) {
      if (from[i] == s)
        str.push_back(make_pair(spell[i], i));
    }

    while (str.size()) {
      string tmp = str[0].first;
      int num = str[0].second;
      int m = 0;
      for (int i = 1; i < (int)str.size(); i++) {
        if (tmp > str[i].first) {
          tmp = str[i].first;
          num = str[i].second;
          m = i;
        }
      }
      if (!use[tmp.size()][to[num]]) {
        ans[tmp.size()][to[num]] = tmp;
        prvx[tmp.size()][to[num]] = tmp.size() - spell[num].size();
        prvy[tmp.size()][to[num]] = from[num];
        use[tmp.size()][to[num]] = true;
        if (to[num] == g)
          break;
        for (int i = 0; i < a; i++) {
          int sum = tmp.size() + spell[i].size();
          if (from[i] == to[num] && sum < 250 && !use[sum][to[num]])
            str.push_back(make_pair(tmp + spell[i], i));
        }
      }
      str.erase(str.begin() + m);
    }

    string res = "NO";
    int pos = -1;
    for (int i = 0; i < 250; i++) {
      if (res == "NO") {
        res = ans[i][g];
        pos = i;
      } else if (ans[i][g] != "NO" && res > ans[i][g]) {
        res = ans[i][g];
        pos = i;
      }
    }

    if (pos >= 0) {
      vector<int> visit;
      int x = pos, y = g;
      bool loop = false;
      visit.push_back(y);
      while (x >= 0 && y >= 0) {
        int t = prvx[x][y];
        y = prvy[x][y];
        x = t;

        for (int i = 0; i < (int)visit.size(); i++) {
          ;
          if (visit[i] == y)
            loop = true;
        }
        if (loop)
          break;
        visit.push_back(y);
      }
      if (loop)
        res = "NO";
    }
    cout << res << endl;
  }
}