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

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

#define fi first
#define se second

#define rep(i, n) for (int i = 0; i < (n); i++)

typedef pair<int, string> pis;

int n, a, s, g;
vector<vector<pis>> G;
vector<vector<pis>> rG;
bool reachable[50];

pair<string, set<int>> q[40 * 6 + 10];

void dfs(int nd, vector<vector<pis>> &Gra) {
  if (reachable[nd])
    return;
  reachable[nd] = true;
  rep(i, Gra[nd].size()) { dfs(Gra[nd][i].fi, Gra); }
}

int main() {
  while (1) {
    cin >> n >> a >> s >> g;
    G.clear();
    rG.clear();
    rep(i, 50) reachable[i] = false;
    rep(i, 40 * 6 + 10) q[i] = pair<string, set<int>>("", set<int>());
    if (!(n || a || s || g))
      break;
    G.resize(n);
    rG.resize(n);
    rep(i, a) {
      int x, y;
      string lab;
      cin >> x >> y >> lab;
      G[x].push_back(pis(y, lab));
      rG[y].push_back(pis(x, string(lab.rbegin(), lab.rend())));
    }
    dfs(g, rG);

    int len = 0;
    q[0].fi = "";
    q[0].se.insert(s);
    string res, tmp;
    res = tmp = "";
    while (len < 40 * 6 + 10) {
      for (set<int>::iterator it = q[len].se.begin(); it != q[len].se.end();
           it++) {
        if (*it == g) {
          if (res == "")
            res = q[len].fi;
          res = min(res, q[len].fi);
        }
        // 遷移
        rep(i, G[*it].size()) {
          string nex;
          nex = q[len].fi + G[*it][i].se;
          if (!reachable[G[*it][i].fi])
            continue;
          if (nex.size() < 40 * 6 + 10) {
            if (q[nex.size()].fi == "" || nex < q[nex.size()].fi) {
              q[nex.size()].fi = nex;
              q[nex.size()].se.clear();
            }
            if (q[nex.size()].fi == nex) {
              q[nex.size()].se.insert(G[*it][i].fi);
            }
          } else {
            if (tmp == "")
              tmp = nex;
            tmp = min(tmp, nex);
          }
        }
      }
      len++;
    }
    if (res == "" || (tmp != "" && tmp < res))
      cout << "NO" << endl;
    else
      cout << res << endl;
  }
}

Error: MLE

Fixed submission:

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

struct e {
  int to;
  string spell;
  e(int to_, string spell_) {
    to = to_;
    spell = spell_;
  }
  e(){};
  bool operator<(const e &obj) const {
    if (this->spell.size() == obj.spell.size())
      return this->spell > obj.spell;
    return this->spell.size() > obj.spell.size();
  }
};

int n, a, s, g;
vector<vector<e>> edge;

int main() {
  while (cin >> n >> a >> s >> g, n || a || s || g) {
    edge.clear();
    edge.resize(n);
    for (int i = 0; i < a; i++) {
      int x, y;
      string lab;
      cin >> x >> y >> lab;
      edge[x].push_back(e(y, lab));
    }
    vector<vector<string>> memo;
    string res = "-";
    priority_queue<e> q;
    memo.resize(n);
    for (int i = 0; i < memo.size(); i++) {
      memo[i].resize(5000);
      for (int j = 0; j < memo[i].size(); j++)
        memo[i][j] = "-";
    }
    q.push(e(s, ""));
    //		int mx_s = 0;
    while (q.size()) {
      //			mx_s = max(mx_s, (int)q.size());
      e cur = q.top();
      q.pop();

      if (cur.to == g && (res == "-" || res > cur.spell))
        res = cur.spell;

      if (memo[cur.to][cur.spell.size()] == "-")
        memo[cur.to][cur.spell.size()] = cur.spell;
      else if (memo[cur.to][cur.spell.size()] > cur.spell)
        continue;

      for (int i = 0; i < edge[cur.to].size(); i++) {
        string str;
        str = cur.spell +
              ((edge[cur.to][i].spell == "-") ? "" : edge[cur.to][i].spell);
        if (str.size() < 5000 && (memo[edge[cur.to][i].to][str.size()] == "-" ||
                                  memo[edge[cur.to][i].to][str.size()] > str)) {
          memo[edge[cur.to][i].to][str.size()] = str;
          q.push(e(edge[cur.to][i].to, str));
        }
      }
    }

    if (res == "-" || res.size() > 2500)
      cout << "NO" << endl;
    else
      cout << res << endl;
    //		cout << mx_s << endl;
  }
}