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

#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, cost;
};
#define INF (1 << 28)
#define MAX_N 6005
#define MAX_M 2005

struct state {
  int pos, cost;
  bool operator<(const state &p) const { return cost > p.cost; }
};

int n, m, l, cnt;
string si, ti, str;
vector<edge> G[MAX_N];
map<string, int> change;
int T[MAX_M][MAX_M];
int d[MAX_N];

int A[MAX_M];
int B[MAX_M];

void solve(int si) {
  for (int i = 0; i < MAX_N; i++)
    d[i] = INF;
  priority_queue<state> Q;
  d[si] = 0;
  Q.push((state){si, 0});
  while (!Q.empty()) {
    state s = Q.top();
    Q.pop();
    if (s.cost > d[s.pos])
      continue;
    if (s.cost > l)
      break;
    for (int i = 0; i < (int)G[s.pos].size(); i++) {
      edge e = G[s.pos][i];
      if (s.cost + e.cost < d[e.to]) {
        d[e.to] = s.cost + e.cost;
        Q.push((state){e.to, d[e.to]});
      }
    }
  }
}

void init() {
  change.clear();
  for (int i = 0; i < MAX_N; i++) {
    G[i].clear();
  }
}

int main() {
  while (1) {
    cin >> n >> m >> l;
    if (n == 0 && m == 0 && l == 0)
      break;
    l *= 10;

    cin >> si >> ti;
    init();
    cnt = 1;
    for (int i = 0; i < n; i++) {
      cin >> str;
      if (change[str] == 0)
        change[str] = cnt++;
      int a = change[str];
      cin >> str;
      if (change[str] == 0)
        change[str] = cnt++;
      int b = change[str];
      int c;
      cin >> c;
      G[a].push_back((edge){b, c});
      G[b].push_back((edge){a, c});
    }
    vector<int> vec;
    for (int i = 0; i < m; i++) {
      cin >> str;
      vec.push_back(change[str]);
    }

    for (int i = 0; i < m; i++) {
      solve(vec[i]);
      for (int j = 0; j < m; j++) {
        T[i][j] = d[vec[j]];
      }
    }

    int ans = INF;
    solve(change[si]);
    for (int i = 0; i < m; i++)
      A[i] = d[vec[i]];
    if (d[change[ti]] <= l)
      ans = d[change[ti]];

    solve(change[ti]);
    for (int i = 0; i < m; i++)
      B[i] = d[vec[i]];

    priority_queue<state> Q;
    for (int i = 0; i < m; i++) {
      d[i] = INF;
      if (A[i] > l)
        continue;
      d[i] = A[i];
      Q.push((state){i, A[i]});
    }

    while (!Q.empty()) {
      state s = Q.top();
      Q.pop();
      if (s.cost > d[s.pos])
        continue;
      for (int i = 0; i < m; i++) {
        if (T[s.pos][i] > l)
          continue;
        if (s.cost + T[s.pos][i] < d[i]) {
          d[i] = s.cost + T[s.pos][i];
          Q.push((state){i, d[i]});
        }
      }
    }

    for (int i = 0; i < m; i++) {
      if (B[i] > l)
        continue;
      ans = min(ans, d[i] + B[i]);
    }

    if (ans == INF)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, cost;
};
#define INF (1 << 28)
#define MAX_N 6005
#define MAX_L 2005
struct state {
  int pos, pos2, cost;
  bool operator<(const state &p) const { return cost > p.cost; }
};

int n, m, l, cnt;
string si, ti, str;
vector<edge> G[MAX_N];
bool flg[MAX_N];
map<string, int> change;

int d[MAX_N][MAX_L];

int solve(int si, int ti) {
  for (int i = 0; i < cnt; i++)
    for (int j = 0; j <= l * 10; j++)
      d[i][j] = INF;
  d[1][l * 10] = 0;
  priority_queue<state> Q;
  Q.push((state){si, l * 10, 0});
  while (!Q.empty()) {
    state s = Q.top();
    Q.pop();
    if (s.pos == ti)
      return s.cost;
    if (s.cost > d[s.pos][s.pos2])
      continue;
    for (int i = 0; i < (int)G[s.pos].size(); i++) {
      edge e = G[s.pos][i];
      int ncost = s.cost + e.cost;
      int npos = e.to;
      int npos2 = s.pos2 - e.cost;
      if (npos2 < 0)
        continue;

      if (flg[npos])
        npos2 = l * 10;
      if (ncost < d[npos][npos2]) {
        d[npos][npos2] = ncost;
        Q.push((state){npos, npos2, ncost});
      }
    }
  }
  return -1;
}

void init() {
  change.clear();
  for (int i = 0; i < MAX_N; i++) {
    G[i].clear();
    flg[i] = false;
  }
}

int main() {
  while (1) {
    cin >> n >> m >> l;
    if (n == 0 && m == 0 && l == 0)
      break;
    cin >> si >> ti;
    init();
    cnt = 1;
    for (int i = 0; i < n; i++) {
      cin >> str;
      if (change[str] == 0)
        change[str] = cnt++;
      int a = change[str];
      cin >> str;
      if (change[str] == 0)
        change[str] = cnt++;
      int b = change[str];
      int c;
      cin >> c;
      G[a].push_back((edge){b, c});
      G[b].push_back((edge){a, c});
    }
    for (int i = 0; i < m; i++) {
      cin >> str;
      flg[change[str]] = true;
    }
    cout << solve(change[si], change[ti]) << endl;
  }
  return 0;
}