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

#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;

struct edge {
  int to, cost;
};

using edges = vector<edge>;
using graph = vector<edges>;

constexpr int INF = 1e9;

int main() {
  int N, M, cap;
  while (cin >> N >> M >> cap, N) {
    unordered_map<string, int> idx;
    string src, dest;
    cin >> src >> dest;
    graph g(6001);
    idx[src] = 0;
    idx[dest] = 1;
    cap *= 10;
    for (int i = 0; i < N; ++i) {
      string c1, c2;
      int d;
      cin >> c1 >> c2 >> d;
      if (idx.count(c1) == 0) {
        idx[c1] = idx.size();
      }
      if (idx.count(c2) == 0) {
        idx[c2] = idx.size();
      }
      g[idx[c1]].push_back(edge{idx[c2], d});
      g[idx[c2]].push_back(edge{idx[c1], d});
    }
    vector<bool> gas(6001);
    for (int i = 0; i < M; ++i) {
      string s;
      cin >> s;
      gas[idx[s]] = true;
    }
    vector<vector<int>> res(6001, vector<int>(cap + 1, INF));
    res[0][cap] = 0;
    using state = tuple<int, int, int>;
    priority_queue<state, vector<state>, greater<state>> que;
    que.push(make_tuple(0, cap, idx[src]));
    while (!que.empty()) {
      int cd, rest, c;
      tie(cd, rest, c) = que.top();
      que.pop();
      // cout << "c: " << c << " rest: " << rest << "  cd: " << cd << endl;
      if (res[c][rest] < cd) {
        continue;
      }
      for (auto &e : g[c]) {
        if (e.cost > rest) {
          continue;
        }
        int nr = (gas[e.to] ? cap : rest - e.cost);
        if (res[e.to][nr] > res[c][rest] + e.cost) {
          res[e.to][nr] = res[c][rest] + e.cost;
          que.push(make_tuple(res[e.to][nr], nr, e.to));
        }
      }
    }
    int r = *min_element(res[idx[dest]].begin(), res[idx[dest]].end());
    cout << (r == INF ? -1 : r) << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;

struct edge {
  string to;
  int cost;
};

using edges = vector<edge>;
using graph = vector<edges>;

constexpr int INF = 1e9;

int main() {
  int N, M, cap;
  while (cin >> N >> M >> cap, N) {
    string src, dest;
    cin >> src >> dest;
    map<string, vector<edge>> g;
    map<string, bool> gas;
    map<string, vector<int>> res;
    cap *= 10;
    for (int i = 0; i < N; ++i) {
      string c1, c2;
      int d;
      cin >> c1 >> c2 >> d;
      g[c1].push_back(edge{c2, d});
      g[c2].push_back(edge{c1, d});
      if (res[c1].size() == 0) {
        res[c1].resize(cap + 1, INF);
      }
      if (res[c2].size() == 0) {
        res[c2].resize(cap + 1, INF);
      }
    }
    for (int i = 0; i < M; ++i) {
      string s;
      cin >> s;
      gas[s] = true;
    }
    res[src][cap] = 0;
    using state = tuple<int, int, string>;
    priority_queue<state, vector<state>, greater<state>> que;
    que.push(make_tuple(0, cap, src));
    while (!que.empty()) {
      int cd, rest;
      string c;
      tie(cd, rest, c) = que.top();
      que.pop();
      if (res[c][rest] < cd) {
        continue;
      }
      for (auto &e : g[c]) {
        if (e.cost > rest) {
          continue;
        }
        int nr = (gas[e.to] ? cap : rest - e.cost);
        if (res[e.to][nr] > res[c][rest] + e.cost) {
          res[e.to][nr] = res[c][rest] + e.cost;
          que.push(make_tuple(res[e.to][nr], nr, e.to));
        }
      }
    }
    int r = (res[dest].size() == 0
                 ? INF
                 : *min_element(res[dest].begin(), res[dest].end()));
    if (r == INF) {
      cout << -1 << endl;
    } else {
      cout << r << endl;
    }
  }
}