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

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

using namespace std;

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

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
typedef pair<string, int> P;

int main() {
  int N, A, S, G;
  while (cin >> N >> A >> S >> G, N) {
    vector<int> to[40];
    vector<string> spell[40];
    REP(i, A) {
      int u, v;
      string s;
      cin >> u >> v >> s;
      to[u].push_back(v);
      spell[u].push_back(s);
    }
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P("", S));
    string ans = "NO";
    set<P> memo;
    bool reachable[40][40] = {};
    REP(i, N) reachable[i][i] = true;
    REP(i, N) REP(j, to[i].size()) reachable[i][to[i][j]] = true;
    REP(k, N)
    REP(i, N) REP(j, N) reachable[i][j] |= reachable[i][k] & reachable[k][j];
    if (!reachable[S][G])
      goto OUT;
    while (!que.empty()) {
      P p = que.top();
      que.pop();
      if (p.second == G) {
        ans = p.first;
        break;
      }
      if ((int)p.first.size() > N * 6) {
        break;
      }
      if (memo.count(p))
        continue;
      memo.insert(p);
      REP(i, to[p.second].size()) {
        int next = to[p.second][i];
        if (reachable[next][G])
          que.push(P(p.first + spell[p.second][i], next));
      }
    }
  OUT:
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

using namespace std;

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

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
typedef pair<string, int> P;

int main() {
  int N, A, S, G;
  while (cin >> N >> A >> S >> G, N) {
    vector<int> to[40];
    vector<string> spell[40];
    int maxcost[40] = {};
    REP(i, A) {
      int u, v;
      string s;
      cin >> u >> v >> s;
      to[u].push_back(v);
      spell[u].push_back(s);
      maxcost[u] = max(maxcost[u], (int)s.size());
    }
    int BOUND = 0;
    REP(i, N) BOUND += maxcost[i];
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P("", S));
    string ans = "NO";
    while (!que.empty()) {
      P p = que.top();
      que.pop();
      if (p.second == G) {
        ans = p.first;
        break;
      }
      if (p.first.size() > BOUND) {
        break;
      }
      REP(i, to[p.second].size()) {
        que.push(P(p.first + spell[p.second][i], to[p.second][i]));
      }
    }
    cout << ans << endl;
  }
  return 0;
}