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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1e9 + 7;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &i : v)
    is >> i;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> &v) {
  const string delimiter = "\\n";
  REP(i, v.size()) {
    os << v[i];
    if (i != v.size() - 1)
      os << delimiter;
  }
  return os;
}
/*--------------------template--------------------*/

typedef string Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost) {
  g[from].push_back(Edge{from, to, cost});
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n, m, st, go;
  int aaaa = 0;
  while (cin >> n >> m >> st >> go, n) {

    Graph tg(n), r(n);
    REP(i, m) {
      int a, b;
      string s;
      cin >> a >> b >> s;
      add_edge(tg, a, b, s);
      add_edge(r, b, a, s);
    }
    set<int> use;
    use.insert(go);
    queue<int> que;
    que.push(go);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (auto e : r[v]) {
        int u = e.to;
        if (use.count(u) > 0)
          continue;
        use.insert(u);
        que.push(u);
      }
    }
    if (use.count(st) == 0) {
      cout << "NO" << endl;
      continue;
    }
    Graph g(m * 10 + n);
    int tmp = n;
    REP(v, n) {
      if (use.count(v) == 0)
        continue;
      for (auto e : tg[v]) {
        int src = v, dst = tmp;
        int u = e.to;
        string s = e.cost;
        tmp += s.size() - 1;
        if (use.count(u) == 0)
          continue;
        REP(i, s.size() - 1) {
          add_edge(g, src, dst, string{s[i]});
          src = dst;
          dst++;
        }
        add_edge(g, src, u, string{s.back()});
      }
    }

    REP(i, g.size()) { sort(ALL(g[i])); }

    bool ok = false;
    set<pii> vis;
    map<int, string> mp;
    queue<pair<int, string>> que2;
    que2.emplace(st, "");
    while (!que2.empty()) {
      int v = que2.front().first;
      string tmp = que2.front().second;
      que2.pop();
      if (mp[tmp.size()] < tmp)
        continue;
      if (v == go) {
        ok = true;
        cout << tmp << endl;
        break;
      }
      if (tmp.size() > 2500)
        break;
      if (vis.count(pii(v, tmp.size())) == 1)
        continue;
      vis.emplace(v, tmp.size());

      string c = g[v][0].cost;
      for (auto e : g[v]) {
        if (e.cost != c)
          break;
        string nx = tmp + c;
        if (mp.count(nx.size()) == 0)
          mp[nx.size()] = nx;
        else
          chmin(mp[nx.size()], nx);
        que2.emplace(e.to, nx);
      }
    }
    if (!ok)
      cout << "NO" << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1e9 + 7;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &i : v)
    is >> i;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> &v) {
  const string delimiter = "\\n";
  REP(i, v.size()) {
    os << v[i];
    if (i != v.size() - 1)
      os << delimiter;
  }
  return os;
}
/*--------------------template--------------------*/

typedef string Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost) {
  g[from].push_back(Edge{from, to, cost});
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n, m, st, go;
  while (cin >> n >> m >> st >> go, n) {
    Graph tg(n), r(n);
    REP(i, m) {
      int a, b;
      string s;
      cin >> a >> b >> s;
      add_edge(tg, a, b, s);
      add_edge(r, b, a, s);
    }
    set<int> use;
    use.insert(go);
    queue<int> que;
    que.push(go);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (auto e : r[v]) {
        int u = e.to;
        if (use.count(u) > 0)
          continue;
        use.insert(u);
        que.push(u);
      }
    }
    if (use.count(st) == 0) {
      cout << "NO" << endl;
      continue;
    }
    Graph g(m * 10 + n);
    int tmp = n;
    REP(v, n) {
      if (use.count(v) == 0)
        continue;
      for (auto e : tg[v]) {
        int src = v, dst = tmp;
        int u = e.to;
        string s = e.cost;
        tmp += s.size() - 1;
        if (use.count(u) == 0)
          continue;
        REP(i, s.size() - 1) {
          add_edge(g, src, dst, string{s[i]});
          src = dst;
          dst++;
        }
        add_edge(g, src, u, string{s.back()});
      }
    }

    REP(i, g.size()) { sort(ALL(g[i])); }

    bool ok = false;
    set<pii> vis;
    vis.emplace(0, 0);
    map<int, string> mp;
    queue<pair<int, string>> que2;
    que2.emplace(st, "");
    while (!que2.empty()) {
      int v = que2.front().first;
      string tmp = que2.front().second;
      que2.pop();
      if (v == go) {
        ok = true;
        cout << tmp << endl;
        break;
      }
      if (tmp.size() > 10000)
        break;
      if (mp[tmp.size()] < tmp)
        continue;
      string c = g[v][0].cost;
      for (auto e : g[v]) {
        if (e.cost != c)
          break;
        string nx = tmp + c;
        if (vis.count(pii(e.to, nx.size())) == 1)
          continue;
        if (mp.count(nx.size()) == 0)
          mp[nx.size()] = nx;
        else
          chmin(mp[nx.size()], nx);
        que2.emplace(e.to, nx);
        vis.emplace(e.to, nx.size());
      }
    }
    if (!ok)
      cout << "NO" << endl;
  }

  return 0;
}