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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define MAX 6000
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;
struct P {
  int to, d;
  P(int to = -1, int d = -1) : to(to), d(d) {}
};

struct Pox {
  int cur, cost, tank;
  Pox(int cur = -1, int cost = -1, int tank = -1)
      : cur(cur), cost(cost), tank(tank) {}
  bool operator<(const Pox &a) const {
    if (cost != a.cost)
      return cost > a.cost;
    if (tank != a.tank)
      return tank > a.tank;
    return cur < a.cur;
  }
};

typedef vector<P> VP;
typedef vector<VP> VVP;

bool LPG[MAX];
int mincost[MAX][2001];
int N, M, cap;
VP G[MAX];
map<string, int> index;
int idx;

void add_edge(string s, string t, int d) {
  if (index.find(s) == index.end())
    index[s] = idx++;
  if (index.find(t) == index.end())
    index[t] = idx++;
  int sindex = index[s];
  int tindex = index[t];
  G[sindex].push_back(P(tindex, d));
  G[tindex].push_back(P(sindex, d));
}

int main() {
  while (cin >> N >> M >> cap, N | M | cap) {
    string ssrc, sdest;
    int src, dest;

    idx = 0;
    index.clear();
    rep(i, MAX) G[i].clear();
    cin >> ssrc >> sdest;
    index[ssrc] = idx++;
    index[sdest] = idx++;
    src = 0, dest = 1;

    rep(i, N) {
      string c1, c2;
      int d;
      cin >> c1 >> c2 >> d;
      add_edge(c1, c2, d);
    }

    assert(idx <= MAX);

    rep(i, idx) {
      LPG[i] = false;
      rep(j, 2001) mincost[i][j] = (1 << 29);
    }

    rep(i, M) {
      string s;
      cin >> s;
      LPG[index[s]] = true;
    }

    int ans = (1 << 29);
    priority_queue<Pox> que;
    que.push(Pox(src, 0, cap * 10));
    mincost[src][cap * 10] = 0;

    while (!que.empty()) {
      Pox pox = que.top();
      que.pop();

      if (ans <= pox.cost)
        continue;

      if (pox.cur == dest) {
        ans = min(ans, pox.cost);
        break;
      }

      for (int i = 0; i < G[pox.cur].size(); i++) {
        P p = G[pox.cur][i];
        int fuelConsumption = pox.tank - p.d;
        int next = p.to;
        if (p.d > pox.tank)
          continue;
        if (p.d == pox.tank && !LPG[next] && next != dest)
          continue;

        if (mincost[next][fuelConsumption] > pox.cost + p.d) {
          mincost[next][fuelConsumption] = pox.cost + p.d;
          if (LPG[next]) {
            que.push(Pox(next, mincost[next][fuelConsumption], cap * 10));
            for (int j = cap * 10; j >= 0; j--)
              mincost[next][j] = min(mincost[next][j], mincost[next][cap * 10]);
          } else {
            que.push(
                Pox(next, mincost[next][fuelConsumption], fuelConsumption));
            for (int j = fuelConsumption; j >= 0; j--)
              mincost[next][j] =
                  min(mincost[next][j], mincost[next][fuelConsumption]);
          }
        }
      }
    }
    ans == (1 << 29) ? cout << -1 << endl : cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define MAX 6000
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;
struct P {
  int to, d;
  P(int to = -1, int d = -1) : to(to), d(d) {}
};

struct Pox {
  int cur, cost, tank;
  Pox(int cur = -1, int cost = -1, int tank = -1)
      : cur(cur), cost(cost), tank(tank) {}
  bool operator<(const Pox &a) const {
    if (cost != a.cost)
      return cost > a.cost;
    if (tank != a.tank)
      return tank > a.tank;
    return cur < a.cur;
  }
};

typedef vector<P> VP;
typedef vector<VP> VVP;

bool LPG[MAX];
int mincost[MAX][2001];
int N, M, cap;
string ssrc, sdest;
int src, dest;
VP G[MAX];
map<string, int> index;
int idx;

void add_edge(string s, string t, int d) {
  if (index.find(s) == index.end())
    index[s] = idx++;
  if (index.find(t) == index.end())
    index[t] = idx++;
  int sindex = index[s];
  int tindex = index[t];
  G[sindex].push_back(P(tindex, d));
  G[tindex].push_back(P(sindex, d));
}

int main() {
  while (cin >> N >> M >> cap, N | M | cap) {
    idx = 0;
    index.clear();
    rep(i, MAX) G[i].clear();
    cin >> ssrc >> sdest;
    index[ssrc] = idx++;
    index[sdest] = idx++;
    src = 0, dest = 1;

    rep(i, N) {
      string c1, c2;
      int d;
      cin >> c1 >> c2 >> d;
      add_edge(c1, c2, d);
    }

    assert(idx <= MAX);

    rep(i, idx) {
      LPG[i] = false;
      rep(j, 2001) mincost[i][j] = (1 << 29);
    }

    rep(i, M) {
      string s;
      cin >> s;
      LPG[index[s]] = true;
    }

    int ans = (1 << 29);
    priority_queue<Pox> que;
    que.push(Pox(src, 0, cap * 10));
    mincost[src][cap * 10] = 0;

    while (!que.empty()) {
      Pox pox = que.top();
      que.pop();

      if (ans <= pox.cost)
        continue;

      if (pox.cur == dest) {
        ans = min(ans, pox.cost);
        break;
      }

      for (int i = 0; i < G[pox.cur].size(); i++) {
        P p = G[pox.cur][i];
        int fuelConsumption = pox.tank - p.d;
        int next = p.to;
        if (p.d > pox.tank)
          continue;
        if (p.d == pox.tank && !LPG[next])
          continue;

        if (mincost[next][fuelConsumption] > pox.cost + p.d) {
          mincost[next][fuelConsumption] = pox.cost + p.d;
          if (LPG[next])
            que.push(Pox(next, mincost[next][fuelConsumption], cap * 10));
          else
            que.push(
                Pox(next, mincost[next][fuelConsumption], fuelConsumption));
        }
      }
    }
    ans == (1 << 29) ? cout << -1 << endl : cout << ans << endl;
  }
  return 0;
}