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

#include <bits/stdc++.h>
using namespace std;

struct edge {
  int to;
  string s;
};
struct state {
  int id, len;
  string s;
  bool operator<(const state &st) const { return s > st.s; }
};

vector<edge> G[55];
int N, M, S, T;
string H[55][500];
string dijk() {
  for (int i = 0; i < N; i++)
    for (int j = 0; j < 500; j++)
      H[i][j] = "~";
  priority_queue<state> q;
  H[S][0] = "";
  q.push((state){S, 0, ""});
  while (!q.empty()) {
    state p = q.top();
    q.pop();
    if (H[p.id][p.len] < p.s)
      continue;
    for (int i = 0; i < (int)G[p.id].size(); i++) {
      edge e = G[p.id][i];
      int nlen = p.len + e.s.size();
      if (nlen >= 500)
        continue;
      if (H[e.to][nlen] > p.s + e.s) {
        H[e.to][nlen] = p.s + e.s;
        q.push((state){e.to, nlen, p.s + e.s});
      }
    }
  }
  string res = "~";
  for (int i = 0; i < 500; i++) {
    if (res > H[T][i]) {
      res = H[T][i];
      if (i > 300)
        return "NO";
    }
  }
  if (res == "~")
    return "NO";
  return res;
}

int main() {
  while (cin >> N >> M >> S >> T && (N | M | S | T)) {
    for (int i = 0; i < M; i++) {
      int a, b;
      string s;
      cin >> a >> b >> s;
      G[a].push_back((edge){b, s});
    }
    cout << dijk() << endl;
    for (int i = 0; i < N; i++)
      G[i].clear();
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

struct edge {
  int to;
  string s;
  string rs;
  edge() { rs = "~"; }
  edge(int to, string s) : to(to), s(s) { rs = "~"; }
  edge(int to, string s, string rs) : to(to), s(s), rs(rs) {}
  bool operator<(const edge &e) const { return rs < e.rs; }
};

vector<edge> G[50];
int rG[50];
int N, M, S, T;
int used[55];

string dfs(int id, string now) {
  if (used[id])
    return "NO";
  if (id == T)
    return now;
  used[id] = true;
  for (int i = 0; i < (int)G[id].size(); i++) {
    string ret = dfs(G[id][i].to, now + G[id][i].s);
    if (ret != "NO")
      return ret;
  }
  return "NO";
}
string dfs2(int id, string now, const string &res) {
  if (used[id] == 5 * N)
    return "NO";
  if (id == T && res > now) {
    return now;
  }
  used[id]++;
  for (int i = 0; i < (int)G[id].size(); i++) {
    string ret = dfs2(G[id][i].to, now + G[id][i].s, res);
    if (ret != "NO") {
      return ret;
    }
  }
  return "NO";
}

string solve() {
  memset(used, 0, sizeof(used));
  string res = dfs(S, "");
  string tmp;
  if ((tmp = dfs2(S, "", res)) != "NO") {
    // cout << "tmp " <<  res << " "<< tmp << endl;
    return "NO";
  }
  return res;
}

int main() {
  while (cin >> N >> M >> S >> T && (N || M || S || T)) {
    for (int i = 0; i < M; i++) {
      int s, t;
      string l;
      cin >> s >> t >> l;
      G[s].push_back(edge(t, l));
    }

    for (int i = 0; i < N; i++) {
      int n = G[i].size();
      for (int j = 0; j < n; j++) {
        edge &e = G[i][j];
        if (e.to == T)
          e.rs = e.s;
        for (int k = 0; k < (int)G[e.to].size(); k++) {
          edge ne = G[e.to][k];
          e.rs = min(e.rs, e.s + ne.s);
        }
      }
      if (!G[i].empty())
        sort(G[i].begin(), G[i].end());
    }

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