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

#include <algorithm>
#include <cstdio>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct edge {
  int t, c;
  edge() {}
  edge(int t, int c) : t(t), c(c) {}
};

struct state {
  int n, cap, c;
  state() {}
  state(int n, int cap, int c) : n(n), cap(cap), c(c) {}
  bool operator>(const state &e) const { return c > e.c; }
};

char s[22], t[22];
char c[3000][22], d[3000][22];
char st[333][22];
int w[3000];
vector<edge> g[6011];
// vector<vector<edge> > g;

vector<bool> sta;
// vector<vector<int> > cost;
unsigned short cost[6011][2001];
int from, to;

int main(void) {
  int n, m, cap;
  for (;;) {
    scanf("%d%d%d", &n, &m, &cap);
    if (n + m + cap == 0)
      break;
    {
      vector<string> node;
      scanf("%s%s", s, t);
      node.push_back(s);
      node.push_back(t);
      for (int i = 0; i < n; i++) {
        scanf("%s%s%d", c[i], d[i], w + i);
        node.push_back(c[i]);
        node.push_back(d[i]);
      }
      for (int i = 0; i < m; i++) {
        scanf("%s", st[i]);
        node.push_back(st[i]);
      }
      sort(node.begin(), node.end());
      node.erase(unique(node.begin(), node.end()), node.end());
      int sz = node.size();
      // g.clear();
      // cost.clear();
      sta.clear();
      // g.resize(sz,vector<edge>());
      // cost.resize(sz,vector<int>(cap*10+1));
      sta.resize(sz);
      for (int i = 0; i < sz; i++) {
        sta[i] = false;
        g[i].clear();
        for (int j = 0; j <= cap * 10; j++) {
          // cost[i][j] = 1919810893;
          cost[i][j] = 65535;
        }
      }
      for (int i = 0; i < n; i++) {
        int a = lower_bound(node.begin(), node.end(), c[i]) - node.begin();
        int b = lower_bound(node.begin(), node.end(), d[i]) - node.begin();
        g[a].push_back(edge(b, w[i]));
        g[b].push_back(edge(a, w[i]));
      }
      for (int i = 0; i < m; i++) {
        sta[lower_bound(node.begin(), node.end(), st[i]) - node.begin()] = true;
      }
      from = lower_bound(node.begin(), node.end(), s) - node.begin();
      to = lower_bound(node.begin(), node.end(), t) - node.begin();
    }
    priority_queue<state, vector<state>, greater<state>> q;
    q.push(state(from, cap * 10, 0));
    cost[from][cap * 10] = 0;
    int res = -1;
    while (!q.empty()) {
      state p = q.top();
      q.pop();
      if (p.n == to) {
        res = p.c;
        break;
      }
      if (cost[p.n][p.cap] < p.c)
        continue;
      for (int i = 0; i < int(g[p.n].size()); i++) {
        edge &e = g[p.n][i];
        int c = p.c + e.c;
        int ncap = p.cap - e.c;
        if (ncap < 0)
          continue;
        if (sta[e.t])
          ncap = cap * 10;
        if (cost[e.t][ncap] > c) {
          cost[e.t][ncap] = c;
          q.push(state(e.t, ncap, c));
        }
      }
    }
    printf("%d\\n", res);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct edge {
  int t, c;
  edge() {}
  edge(int t, int c) : t(t), c(c) {}
};

struct state {
  int n, cap, c;
  state() {}
  state(int n, int cap, int c) : n(n), cap(cap), c(c) {}
  bool operator>(const state &e) const { return c > e.c; }
};

char s[22], t[22];
char c[3000][22], d[3000][22];
char st[333][22];
int w[3000];
vector<edge> g[6011];
// vector<vector<edge> > g;

vector<bool> sta;
// vector<vector<int> > cost;
int cost[6011][2001];
int from, to;

int main(void) {
  int n, m, cap;
  for (;;) {
    scanf("%d%d%d", &n, &m, &cap);
    if (n + m + cap == 0)
      break;
    {
      vector<string> node;
      scanf("%s%s", s, t);
      node.push_back(s);
      node.push_back(t);
      for (int i = 0; i < n; i++) {
        scanf("%s%s%d", c[i], d[i], w + i);
        node.push_back(c[i]);
        node.push_back(d[i]);
      }
      for (int i = 0; i < m; i++) {
        scanf("%s", st[i]);
        node.push_back(st[i]);
      }
      sort(node.begin(), node.end());
      node.erase(unique(node.begin(), node.end()), node.end());
      int sz = node.size();
      // g.clear();
      // cost.clear();
      sta.clear();
      // g.resize(sz,vector<edge>());
      // cost.resize(sz,vector<int>(cap*10+1));
      sta.resize(sz);
      for (int i = 0; i < sz; i++) {
        sta[i] = false;
        g[i].clear();
        for (int j = 0; j <= cap * 10; j++) {
          cost[i][j] = 1919810893;
        }
      }
      for (int i = 0; i < n; i++) {
        int a = lower_bound(node.begin(), node.end(), c[i]) - node.begin();
        int b = lower_bound(node.begin(), node.end(), d[i]) - node.begin();
        g[a].push_back(edge(b, w[i]));
        g[b].push_back(edge(a, w[i]));
      }
      for (int i = 0; i < m; i++) {
        sta[lower_bound(node.begin(), node.end(), st[i]) - node.begin()] = true;
      }
      from = lower_bound(node.begin(), node.end(), s) - node.begin();
      to = lower_bound(node.begin(), node.end(), t) - node.begin();
    }
    priority_queue<state, vector<state>, greater<state>> q;
    q.push(state(from, cap * 10, 0));
    cost[from][cap * 10] = 0;
    int res = -1;
    while (!q.empty()) {
      state p = q.top();
      q.pop();
      if (p.n == to) {
        res = p.c;
        break;
      }
      if (cost[p.n][p.cap] < p.c)
        continue;
      for (int i = 0; i < int(g[p.n].size()); i++) {
        edge &e = g[p.n][i];
        int c = p.c + e.c;
        int ncap = p.cap - e.c;
        if (ncap < 0)
          continue;
        if (sta[e.t])
          ncap = cap * 10;
        if (cost[e.t][ncap] > c) {
          cost[e.t][ncap] = c;
          q.push(state(e.t, ncap, c));
        }
      }
    }
    printf("%d\\n", res);
  }
  return 0;
}