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

#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

typedef vector<pii> vp;
typedef vector<vp> vvp;
struct node {
  int index, gas, cost;
  node(int index, int gas, int cost) : index(index), gas(gas), cost(cost) {}
  bool operator<(const node &other) const { return cost > other.cost; }
};
const int MAX = INT_MAX / 2 - 10;
const int NONE = -1;

int main() {
  int r, m, cap;
  while (cin >> r >> m >> cap, r | m | cap) {
    cap *= 10;
    string src, dest;
    cin >> src >> dest;
    int start;
    int goal;
    vvp dist;
    vs cities;
    REP(i, r) {
      string a, b;
      cin >> a >> b;
      int d;
      cin >> d;
      int ai, bi;
      vs::iterator it_a = find(ALL(cities), a);
      if (it_a != cities.end()) {
        ai = it_a - cities.begin();
      } else {
        cities.push_back(a);
        ai = cities.size() - 1;
        dist.push_back(vp());
      }
      vs::iterator it_b = find(ALL(cities), b);
      if (it_b != cities.end()) {
        bi = it_b - cities.begin();
      } else {
        cities.push_back(b);
        bi = cities.size() - 1;
        dist.push_back(vp());
      }
      dist[ai].push_back(make_pair(bi, d));
      dist[bi].push_back(make_pair(ai, d));
      if (a == src) {
        start = ai;
      }
      if (b == src) {
        start = bi;
      }
      if (a == dest) {
        goal = ai;
      }
      if (b == dest) {
        goal = bi;
      }
    }
    int n = cities.size();
    vi is_station(n);
    REP(i, m) {
      string s;
      cin >> s;
      vs::iterator it = find(ALL(cities), s);
      if (it != cities.end()) {
        is_station[it - cities.begin()] = 1;
      }
    }

    priority_queue<node> q;
    q.push(node(start, cap, 0));
    vvi cost(n, vi(cap + 1, MAX));
    cost[start][cap] = 0;
    while (!q.empty()) {
      node cnode = q.top();
      q.pop();
      if (cost[cnode.index][cnode.gas] < cnode.cost) {
        continue;
      }
      REP(ii, dist[cnode.index].size()) {
        int i = dist[cnode.index][ii].first;
        int dd = dist[cnode.index][ii].second;
        if (i != cnode.index && dd != NONE) {
          int newcost = cnode.cost + dd;
          int newgas = cnode.gas - dd;
          if (newgas >= 0) {
            if (is_station[i]) {
              newgas = cap;
            }
            if (cost[i][newgas] > newcost) {
              cost[i][newgas] = newcost;
              q.push(node(i, newgas, newcost));
            }
          }
        }
      }
    }
    int ans = MAX;
    REP(i, cap + 1) { ans = min(ans, cost[goal][i]); }

    cout << (ans == MAX ? -1 : ans) << endl;
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<pii> vp;
typedef vector<vp> vvp;
struct node {
  int index, gas;
  ll cost;
  node(int index, int gas, ll cost) : index(index), gas(gas), cost(cost) {}
  bool operator<(const node &other) const { return cost > other.cost; }
};
const ll MAX = LLONG_MAX / 10;
const int NONE = -1;

int main() {
  int r, m, cap;
  while (cin >> r >> m >> cap, r | m | cap) {
    cap *= 10;
    string src, dest;
    cin >> src >> dest;
    int start;
    int goal;
    vvp dist;
    vs cities;
    REP(i, r) {
      string a, b;
      cin >> a >> b;
      int d;
      cin >> d;
      int ai, bi;
      vs::iterator it_a = find(ALL(cities), a);
      if (it_a != cities.end()) {
        ai = it_a - cities.begin();
      } else {
        cities.push_back(a);
        ai = cities.size() - 1;
        dist.push_back(vp());
      }
      vs::iterator it_b = find(ALL(cities), b);
      if (it_b != cities.end()) {
        bi = it_b - cities.begin();
      } else {
        cities.push_back(b);
        bi = cities.size() - 1;
        dist.push_back(vp());
      }
      dist[ai].push_back(make_pair(bi, d));
      dist[bi].push_back(make_pair(ai, d));
      if (a == src) {
        start = ai;
      }
      if (b == src) {
        start = bi;
      }
      if (a == dest) {
        goal = ai;
      }
      if (b == dest) {
        goal = bi;
      }
    }
    int n = cities.size();
    vi is_station(n);
    REP(i, m) {
      string s;
      cin >> s;
      vs::iterator it = find(ALL(cities), s);
      if (it != cities.end()) {
        is_station[it - cities.begin()] = 1;
      }
    }

    priority_queue<node> q;
    q.push(node(start, cap, 0));
    vvl cost(n, vl(cap + 1, MAX));
    cost[start][cap] = 0;
    while (!q.empty()) {
      node cnode = q.top();
      q.pop();
      if (cost[cnode.index][cnode.gas] < cnode.cost) {
        continue;
      }
      REP(ii, dist[cnode.index].size()) {
        int i = dist[cnode.index][ii].first;
        int dd = dist[cnode.index][ii].second;
        if (i != cnode.index && dd != NONE) {
          ll newcost = cnode.cost + dd;
          int newgas = cnode.gas - dd;
          if (newgas >= 0) {
            if (is_station[i]) {
              newgas = cap;
            }
            if (cost[i][newgas] > newcost) {
              cost[i][newgas] = newcost;
              q.push(node(i, newgas, newcost));
            }
          }
        }
      }
    }
    ll ans = MAX;
    REP(i, cap + 1) { ans = min(ans, cost[goal][i]); }

    cout << (ans == MAX ? -1 : ans) << endl;
  }
}