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

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

struct edge {
  int v;
  string cost;
  edge(int v_, string cost_) {
    v = v_;
    cost = cost_;
  }
};
bool operator<(const edge &a, const edge &b) { return a.cost > b.cost; }
const int MAX_V = 40;
const int MAX_E = 400;
// dp[v][l] :=
// テヲツ慊?・ツセツ古」ツ?ォティツィツェテ」ツつ古」ツ?淌ゥツ?づァツつケテ」ツ??v
// テ」ツ?ァテゥツ閉キテ」ツ?陛」ツ??l
// テ」ツ?ョテヲツ鳴?・ツュツ療・ツ按療」ツ?ョテヲツ慊?・ツーツ湘」ツ?ョテヲツ鳴?・ツュツ療・ツ按?
string dp[MAX_V][500];
vector<edge> G[MAX_V];
int n, a, s, g;

void add_edge(int u, int v, string cost) { G[u].push_back(edge(v, cost)); }

void dfs(int v, vector<bool> &visited) {
  visited[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int to = G[v][i].v;
    if (!visited[to]) {
      dfs(to, visited);
    }
  }
}

bool is_exist() {
  // テ」ツつエテ」ツδシテ」ツδォテ」ツ?ォテ・ツ按ーテゥツ?氾・ツ渉ッティツδステ」ツ?凝」ツ?ゥテ」ツ??」ツ??
  vector<bool> visited(n, false);
  dfs(s, visited);
  if (!visited[g])
    return false;

  return true;
}

string solve() {
  for (int i = 0; i < MAX_V; i++) {
    fill(dp[i], dp[i] + 500, "~");
  }
  // テ」ツδォテ」ツδシテ」ツδ療」ツ?療」ツ?ェテ」ツ??」ツ?ィテ」ツ?催」ツ?ョテ・ツ堕ェテヲツ鳴?」ツ?ョテヲツ慊?・ツ、ツァテゥツ閉キ
  int N = 6 * (n - 1);
  dp[s][0] = "";
  priority_queue<edge> q;
  q.push(edge(s, ""));

  string res = "~";
  while (!q.empty()) {
    int v = q.top().v;
    string cost = q.top().cost;
    int l = cost.size();
    q.pop();

    if (v == g) {
      res = min(res, cost);
      break;
    }

    for (int i = 0; i < G[v].size(); i++) {
      int to = G[v][i].v;
      string add_cost = G[v][i].cost;
      string next_cost = cost + add_cost;
      int l_ = next_cost.size();
      if (500 <= next_cost.size()) {
        continue;
      }
      if (next_cost < dp[to][l_]) {
        dp[to][l_] = next_cost;
        q.push(edge(to, dp[to][l_]));
      }
    }
  }
  for (int i = N; i < 500; i++) {
    if (dp[g][i].size() == i)
      return "~";
  }
  return res;
}

int main() {
  while (cin >> n >> a >> s >> g, n) {
    // テ・ツ按敕ヲツ慊淌・ツ個?
    for (int i = 0; i < MAX_V; i++)
      G[i].clear();

    for (int i = 0; i < a; i++) {
      int x, y;
      string lab;
      cin >> x >> y >> lab;
      add_edge(x, y, lab);
    }
    if (!is_exist()) {
      cout << "NO" << endl;
    } else {
      string ans = solve();
      if (ans == "~")
        ans = "NO";
      cout << ans << endl;
    }
  }
}

Error: MLE

Fixed submission:

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

struct edge {
  int v;
  string cost;
  edge(int v_, string cost_) {
    v = v_;
    cost = cost_;
  }
};
bool operator<(const edge &a, const edge &b) { return a.cost > b.cost; }
const int MAX_V = 40;
const int MAX_E = 400;
// dp[v][l] :=
// テヲツ慊?・ツセツ古」ツ?ォティツィツェテ」ツつ古」ツ?淌ゥツ?づァツつケテ」ツ??v
// テ」ツ?ァテゥツ閉キテ」ツ?陛」ツ??l
// テ」ツ?ョテヲツ鳴?・ツュツ療・ツ按療」ツ?ョテヲツ慊?・ツーツ湘」ツ?ョテヲツ鳴?・ツュツ療・ツ按?
string dp[MAX_V][2500];
vector<edge> G[MAX_V];
int n, a, s, g;

void add_edge(int u, int v, string cost) { G[u].push_back(edge(v, cost)); }

void dfs(int v, vector<bool> &visited) {
  visited[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int to = G[v][i].v;
    if (!visited[to]) {
      dfs(to, visited);
    }
  }
}

bool is_exist() {
  // テ」ツつエテ」ツδシテ」ツδォテ」ツ?ォテ・ツ按ーテゥツ?氾・ツ渉ッティツδステ」ツ?凝」ツ?ゥテ」ツ??」ツ??
  vector<bool> visited(n, false);
  dfs(s, visited);
  if (!visited[g])
    return false;

  return true;
}

string solve() {
  for (int i = 0; i < MAX_V; i++) {
    fill(dp[i], dp[i] + 2500, "~");
  }
  // テ」ツδォテ」ツδシテ」ツδ療」ツ?療」ツ?ェテ」ツ??」ツ?ィテ」ツ?催」ツ?ョテ・ツ堕ェテヲツ鳴?」ツ?ョテヲツ慊?・ツ、ツァテゥツ閉キ
  int N = 6 * (n - 1);
  dp[s][0] = "";
  priority_queue<edge> q;
  q.push(edge(s, ""));

  string res = "~";
  while (!q.empty()) {
    int v = q.top().v;
    string cost = q.top().cost;
    int l = cost.size();
    q.pop();

    if (v == g) {
      res = min(res, cost);
      break;
    }

    for (int i = 0; i < G[v].size(); i++) {
      int to = G[v][i].v;
      string add_cost = G[v][i].cost;
      string next_cost = cost + add_cost;
      int l_ = next_cost.size();
      if (2500 <= next_cost.size()) {
        continue;
      }
      if (next_cost < dp[to][l_]) {
        dp[to][l_] = next_cost;
        q.push(edge(to, dp[to][l_]));
      }
    }
  }
  for (int i = N; i < 2500; i++) {
    if (dp[g][i].size() == i)
      return "~";
  }
  return res;
}

int main() {
  while (cin >> n >> a >> s >> g, n) {
    // テ・ツ按敕ヲツ慊淌・ツ個?
    for (int i = 0; i < MAX_V; i++)
      G[i].clear();

    for (int i = 0; i < a; i++) {
      int x, y;
      string lab;
      cin >> x >> y >> lab;
      add_edge(x, y, lab);
    }
    if (!is_exist()) {
      cout << "NO" << endl;
    } else {
      string ans = solve();
      if (ans == "~")
        ans = "NO";
      cout << ans << endl;
    }
  }
}