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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

#define MAX 1000
#define EPS (1e-10)
using namespace std;

typedef unsigned int uint;
typedef long long ll;

int main() {
  int n, a, s, g;
  while (cin >> n >> a >> s >> g, n + a + s + g) {
    vector<vector<pair<int, string>>> l(n);
    vector<vector<bool>> canGo(n, vector<bool>(n));
    vector<bool> reach(n);
    REP(i, a) {
      int x, y;
      string s;
      cin >> x >> y >> s;
      l[x].push_back(mp(y, s));
      canGo[x][y] = true;
    }

    REP(i, n) {
      if (l[i].size() != 0) {
        sort(l[i].begin(), l[i].end());
        vector<pair<int, string>>::iterator it = l[i].begin();
        string s1;
        while (it != l[i].end()) {
          if (it != l[i].begin() && it->f == (it - 1)->f) {
            string s2 = it->s;
            if (s1.length() > s2.length() || s1 != s2.substr(0, s1.length())) {
              it = l[i].erase(it);
            } else {
              it++;
            }
          } else {
            s1 = it->s;
            it++;
          }
        }
      }
    }

    REP(k, n)
    REP(i, n) REP(j, n) canGo[i][j] =
        (canGo[i][j] | (canGo[i][k] & canGo[k][j]));

    REP(i, n) reach[i] = canGo[i][g];
    reach[g] = true;

    string ans;
    typedef pair<string, int> pp;
    priority_queue<pp, vector<pp>, greater<pp>> pq;
    vector<set<string>> memo(n);

    if (!reach[s]) {
      ans = "NO";
      goto end;
    }

    pq.push(mp("", s));
    while (true) {
      pp p = pq.top();
      int now = p.s;
      string sp = p.f;
      pq.pop();

      if (now == g) {
        ans = sp;
        goto end;
      }

      if (sp.length() >= 6 * n) {
        ans = "NO";
        goto end;
      }

      FOR(it, l[now]) {
        int dist = it->f;
        string s = it->s;

        if (reach[dist]) {
          if (memo[dist].find(sp + s) == memo[dist].end()) {
            memo[dist].insert(sp + s);
            pq.push(mp(sp + s, dist));
          }
        }
      }
    }

  end:
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

#define MAX 1000
#define EPS (1e-10)
using namespace std;

typedef unsigned int uint;
typedef long long ll;

int main() {
  int n, a, s, g;
  while (cin >> n >> a >> s >> g, n + a + s + g) {
    vector<vector<pair<int, string>>> l(n);
    vector<vector<bool>> canGo(n, vector<bool>(n));
    vector<bool> reach(n);
    REP(i, a) {
      int x, y;
      string s;
      cin >> x >> y >> s;
      l[x].push_back(mp(y, s));
      canGo[x][y] = true;
    }

    REP(i, n) {
      if (l[i].size() != 0) {
        sort(l[i].begin(), l[i].end());
        vector<pair<int, string>>::iterator it = l[i].begin();
        string s1;
        while (it != l[i].end()) {
          if (it != l[i].begin() && it->f == (it - 1)->f) {
            string s2 = it->s;
            if (s1.length() > s2.length() || s1 != s2.substr(0, s1.length())) {
              it = l[i].erase(it);
            } else {
              it++;
            }
          } else {
            s1 = it->s;
            it++;
          }
        }
      }
    }

    REP(k, n)
    REP(i, n) REP(j, n) canGo[i][j] =
        (canGo[i][j] | (canGo[i][k] & canGo[k][j]));

    REP(i, n) reach[i] = canGo[i][g];
    reach[g] = true;

    string ans;
    typedef pair<string, int> pp;
    priority_queue<pp, vector<pp>, greater<pp>> pq;

    if (!reach[s]) {
      ans = "NO";
      goto end;
    }

    pq.push(mp("", s));
    while (true) {
      pp p = pq.top();
      int now = p.s;
      string sp = p.f;
      pq.pop();

      if (now == g) {
        ans = sp;
        goto end;
      }

      if (sp.length() >= 6 * n) {
        ans = "NO";
        goto end;
      }

      FOR(it, l[now]) {
        int dist = it->f;
        string s = it->s;

        if (reach[dist])
          pq.push(mp(sp + s, dist));
      }
    }

  end:
    cout << ans << endl;
  }
  return 0;
}