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

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

const int MAX_N = 6001;
const int MAX_CAP = 2002;

struct Edge {
  int to, cost;
  Edge() {}
  Edge(int to, int cost) : to(to), cost(cost) {}
};

struct State {
  int p, cost, oil;
  State() {}
  State(int p, int cost, int oil) : p(p), cost(cost), oil(oil) {}
  bool operator<(const State &s) const {
    if (cost != s.cost)
      return cost > s.cost;
    if (oil != s.oil)
      return oil < s.oil;
    return p < s.p;
  }
};

int Cap, num, Src, Dist;

map<string, int> id;
vector<Edge> E[MAX_N];

bool existS[MAX_N];
bool cost[MAX_N][MAX_CAP];

int getId(string s) {
  if (id.find(s) == id.end()) {
    id[s] = num++;
  }
  return id[s];
}

int solve() {
  priority_queue<State> que;
  State s(Src, 0, Cap);
  que.push(s);
  fill(cost[0], cost[num], 0);
  while (!que.empty()) {

    s = que.top();
    que.pop();
    //    cout << s.p << ", " << s.cost << ", " << s.oil << endl;
    if (cost[s.p][s.oil])
      continue;
    cost[s.p][s.oil] = true;

    if (s.p == Dist)
      return s.cost;

    for (int i = 0; i < E[s.p].size(); ++i) {
      int nextOil = s.oil - E[s.p][i].cost;
      if (nextOil < 0)
        continue;
      if (existS[E[s.p][i].to])
        nextOil = Cap;
      if (cost[E[s.p][i].to][nextOil])
        continue;

      que.push(State(E[s.p][i].to, s.cost + E[s.p][i].cost, nextOil));
    }
  }
  return -1;
}

int main() {
  int N, M;
  while (cin >> N >> M >> Cap && (N | M | Cap)) {
    num = 0;
    Cap *= 10;
    id.clear();
    for (int i = 0; i < MAX_N; ++i)
      E[i].clear();

    string src, dist;
    cin >> src >> dist;
    Src = getId(src);
    Dist = getId(dist);
    for (int i = 0; i < N; ++i) {
      string from, to;
      int d;
      cin >> from >> to >> d;
      E[getId(from)].push_back(Edge(getId(to), d));
      E[getId(to)].push_back(Edge(getId(from), d));
    }

    fill(existS, existS + MAX_N, false);
    for (int i = 0; i < M; ++i) {
      string name;
      cin >> name;
      existS[getId(name)] = true;
    }
    cout << solve() << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

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

const int MAX_N = 6001;
const int MAX_CAP = 2002;

struct Edge {
  int to, cost;
  Edge() {}
  Edge(int to, int cost) : to(to), cost(cost) {}
};

struct State {
  int p, cost, oil;
  State() {}
  State(int p, int cost, int oil) : p(p), cost(cost), oil(oil) {}
  bool operator<(const State &s) const {
    if (cost != s.cost)
      return cost > s.cost;
    if (oil != s.oil)
      return oil < s.oil;
    return p < s.p;
  }
};

int Cap, num, Src, Dist;

map<string, int> id;
vector<Edge> E[MAX_N];

bool existS[MAX_N];
int cost[MAX_N][MAX_CAP];

int getId(string s) {
  if (id.find(s) == id.end()) {
    id[s] = num++;
  }
  return id[s];
}

int solve() {
  priority_queue<State> que;
  State s(Src, 0, Cap);
  que.push(s);
  fill(cost[0], cost[num], -1);
  while (!que.empty()) {

    s = que.top();
    que.pop();
    //    cout << s.p << ", " << s.cost << ", " << s.oil << endl;
    if (cost[s.p][s.oil] != -1)
      continue;
    cost[s.p][s.oil] = s.cost;

    if (s.p == Dist)
      return s.cost;

    for (int i = 0; i < E[s.p].size(); ++i) {
      int nextOil = s.oil - E[s.p][i].cost;
      if (nextOil < 0)
        continue;
      if (existS[E[s.p][i].to])
        nextOil = Cap;
      if (cost[E[s.p][i].to][nextOil] != -1)
        continue;

      que.push(State(E[s.p][i].to, s.cost + E[s.p][i].cost, nextOil));
    }
  }
  return -1;
}

int main() {
  int N, M;
  while (cin >> N >> M >> Cap && (N | M | Cap)) {
    num = 0;
    Cap *= 10;
    id.clear();
    for (int i = 0; i < MAX_N; ++i)
      E[i].clear();

    string src, dist;
    cin >> src >> dist;
    Src = getId(src);
    Dist = getId(dist);
    for (int i = 0; i < N; ++i) {
      string from, to;
      int d;
      cin >> from >> to >> d;
      E[getId(from)].push_back(Edge(getId(to), d));
      E[getId(to)].push_back(Edge(getId(from), d));
    }

    fill(existS, existS + MAX_N, false);
    for (int i = 0; i < M; ++i) {
      string name;
      cin >> name;
      existS[getId(name)] = true;
    }
    cout << solve() << endl;
  }
  return 0;
}