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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// common

#define BR "\\n"
#define ALL(c) (c).begin(), (c).end()
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, l, r) for (int i = (int)l; i < (int)(r); ++i)
#define EACH(it, o) for (auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))

// config
// #define NDEBUG

// debug
#ifdef NDEBUG
#define DUMP(x)
#define DUMPLN(x)
#define DEBUG(x)
#define DEBUGLN(x)
#define LINE()
#define LINELN()
#define CHECK(exp, act)
#define STOP(e)
#else
#define DUMP(x) cerr << #x << " = " << (x)
#define DUMPLN(x) DUMP(x) << endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x) << endl
#define LINE() cerr << " (L" << __LINE__ << ")"
#define LINELN() LINE() << endl
#define CHECK(exp, act)                                                        \\
  if (exp != act) {                                                            \\
    DUMPLN(exp);                                                               \\
    DEBUGLN(act);                                                              \\
  }
#define STOP(e)                                                                \\
  CHECK(e, true);                                                              \\
  if (!(e))                                                                    \\
    exit(1);
#endif

template <class T> inline string toString(const vector<T> &x) {
  stringstream ss;
  REP(i, x.size()) {
    if (i != 0)
      ss << " ";
    ss << x[i];
  }
  return ss.str();
}

template <class T> inline string toString(const vector<vector<T>> &map) {
  stringstream ss;
  REP(i, map.size()) {
    if (i != 0)
      ss << BR;
    ss << toString(map[i]);
  }
  return ss.str();
}
template <class K, class V> string toString(map<K, V> &x) {
  string res;
  stringstream ss;
  for (auto &p : x)
    ss << p.first << ":" << p.second << " ";
  return ss.str();
}

string BITtoString(int bit) {
  stringstream ss;
  while (bit != 0) {
    ss << (bit % 2);
    bit /= 2;
  }
  string res = ss.str();
  reverse(ALL(res));
  return res;
}

template <typename T, typename V> inline T pmod(T v, V MOD) {
  return (v % MOD + MOD) % MOD;
}
char tmp[1000];
#define nextInt(n) scanf("%d", &n)
#define nextLong(n) scanf("%lld", &n)
#define nextDouble(n) scanf("%lf", &n) // I64d
#define nextChar(n) scanf("%c", &n)
#define nextString(n)                                                          \\
  scanf("%s", tmp);                                                            \\
  n = tmp

namespace EGraph {
typedef string Cost;
Cost CINF = string(1, 'z' + 1);
struct Edge {
  int from, to;
  Cost cost;
  Edge(int from, int to, Cost cost) : from(from), to(to), cost(cost){};
  bool operator<(Edge r) const { return cost < r.cost; }
  bool operator>(Edge r) const { return cost > r.cost; }
};
typedef vector<vector<Edge>> Graph;
} // namespace EGraph
using namespace EGraph;

namespace ShortestPath {
using namespace EGraph;

struct Task {
  int prev, pos;
  Cost cost;
  Task(int prev, int pos, Cost cost) : prev(prev), pos(pos), cost(cost){};
  bool operator>(const Task &r) const { return cost > r.cost; }
};

// 最大も可
// 負の閉路が判定可能
// O(V*E)
vector<Cost> bellmanFord(Graph g, int s, int t) {
  const int V = g.size();
  vector<Cost> d(V, CINF);
  d[s] = "";
  REP(k, 6 * V + 10) {
    REP(i, V) REP(j, g[i].size()) {
      Edge &e = g[i][j];
      if (d[e.from] != CINF &&
          (d[e.to] == CINF || d[e.to] > e.cost + d[e.from])) {
        d[e.to] = e.cost + d[e.from];
        if (e.to == t && k >= V)
          d[e.to] = CINF;
      }
    }
  }
  return d;
}
} // namespace ShortestPath
using namespace ShortestPath;
int n, a, s, t;

int main() {

  // ifstream cin("in");
  // ofstream cout( "out" );
  while (true) {
    cin >> n >> a >> s >> t;
    if (!n)
      break;

    Graph g(n);
    REP(i, a) {
      int from, to;
      string lab;
      cin >> from >> to >> lab;
      g[to].push_back(Edge(to, from, lab));
    }

    string res = bellmanFord(g, t, s)[s];
    cout << (res == CINF ? "NO" : res) << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
// #include <tuple>
#include <cmath>
#include <map>
#include <numeric>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
// typedef tuple<int, int, int> T;
typedef pair<ll, ll> Pl;
// typedef tuple<ll, ll, ll> Tl;

vector<vector<string>> G(50, vector<string>(50));
vector<vector<string>> dis(50, vector<string>(50));
vector<vector<string>> loop(50, vector<string>(50));
int n, s, g;
bool find() {
  for (int i = 0; i < n; i++) {
    if (i != g and dis[s][i] + dis[i][g] == dis[s][g]) {
      if (loop[i][i] <= dis[i][g])
        return true;
    }
  }
  return false;
}

int main() {
  string INF = string(1, 'z' + 1);
  while (true) {
    int a;
    cin >> n >> a >> s >> g;
    if (!n)
      break;

    for (int i = 0; i < 50; i++) {
      for (int j = 0; j < 50; j++) {
        G[i][j] = dis[i][j] = loop[i][j] = INF;
      }
    }

    for (int i = 0; i < a; i++) {
      int x, y;
      string lab;
      cin >> x >> y;
      cin >> lab;
      if (lab < G[x][y])
        loop[x][y] = dis[x][y] = G[x][y] = lab;
    }

    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (dis[i][j] > dis[i][k] + dis[k][j])
            dis[i][j] = dis[i][k] + dis[k][j];
          if (loop[i][j] > loop[i][k] + loop[k][j])
            loop[i][j] = loop[i][k] + loop[k][j];
        }
      }
    }

    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (dis[i][j] > dis[i][k] + dis[k][j])
            dis[i][j] = dis[i][k] + dis[k][j];
        }
      }
    }

    if (dis[s][g] >= INF)
      cout << "NO" << endl;
    else {
      dis[s][s] = "";
      if (dis[s][g] != loop[s][g])
        cout << "NO" << endl;
      else
        cout << dis[s][g] << endl;
      // cout << dis[s][g] <<endl;
      // cout << loop[0][0] << endl;
    }
  }
}