Problem p00897 (C++) — buggy submission, verdict: Runtime Error

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

class Edge {
public:
  int from;
  int to;
  int dist;
  Edge() {}
  Edge(int _f, int _t, int _d) : from(_f), to(_t), dist(_d) {}
};

bool is_LPG[3005];
bool dp[3005][2005]; // dp[city_id][remaining_LPG] = dist;
static int gCity_idx = 0;

int get_city_id(map<string, int> &cities, const string &city) {
  if (cities.find(city) == cities.end()) {
    cities[city] = gCity_idx++;
  }
  return cities[city];
}

class State {
public:
  int city_id;
  int dist;
  int remaining_LPG;
  State(int _city_id, int _dist, int _con) {
    city_id = _city_id;
    dist = _dist;
    remaining_LPG = _con;
  }

  bool operator<(const State &s) const { return (dist < s.dist); }

  bool operator>(const State &s) const { return (dist > s.dist); }
};

int main() {
  int total_roads;
  int total_LPG_stations;
  int capacity;
  while (cin >> total_roads >> total_LPG_stations >> capacity) {
    if (total_roads == 0 && total_LPG_stations == 0 && capacity == 0)
      break;
    gCity_idx = 0;

    map<string, int> cities;
    vector<Edge> edges(total_roads);
    memset(is_LPG, false, sizeof(is_LPG));
    memset(dp, false, sizeof(dp));

    string src, dst;
    cin >> src >> dst;
    get_city_id(cities, src);
    get_city_id(cities, dst);

    for (int road_idx = 0; road_idx < total_roads; road_idx++) {
      string from_str, to_str;
      int dist;

      cin >> from_str >> to_str >> dist;
      int from_num = get_city_id(cities, from_str);
      int to_num = get_city_id(cities, to_str);

      edges[road_idx] = Edge(from_num, to_num, dist);
    }

    for (int LPG_idx = 0; LPG_idx < total_LPG_stations; LPG_idx++) {
      string city;
      cin >> city;
      is_LPG[get_city_id(cities, city)] = true;
    }

    priority_queue<State, vector<State>, greater<State>> que;
    que.push(State(get_city_id(cities, src), 0, 10 * capacity));

    int dst_id = get_city_id(cities, dst);

    vector<vector<Edge>> nodes(cities.size());
    for (int i = 0; i < edges.size(); i++) {
      Edge e = edges[i];
      nodes[e.from].push_back(Edge(e.from, e.to, e.dist));
      nodes[e.to].push_back(Edge(e.to, e.from, e.dist));
    }

    int res = INF;
    while (!que.empty()) {
      State s = que.top();
      que.pop();

      if (s.city_id == dst_id) {
        res = s.dist;
        goto found;
      }
      if (dp[s.city_id][s.remaining_LPG])
        continue;
      dp[s.city_id][s.remaining_LPG] = true;

      for (int to_idx = 0; to_idx < nodes[s.city_id].size(); to_idx++) {
        int to = nodes[s.city_id][to_idx].to;
        int dist = nodes[s.city_id][to_idx].dist;
        if (s.remaining_LPG < dist)
          continue;

        int next_remaining_LPG =
            (is_LPG[to] ? 10 * capacity : s.remaining_LPG - dist);

        que.push(State(to, s.dist + dist, next_remaining_LPG));
      }
    }
  found:;
    printf("%d\\n", res >= INF ? -1 : res);
  }
  return 0;
}

Error: 0

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

bool dp[6001][2001]; // dp[city_id][remaining_LPG] = dist;

class Node {
public:
  int to;
  int dist;
  Node() : to(0), dist(0) {}
  Node(int _t, int _d) : to(_t), dist(_d) {}
};

map<string, int> cities;
bool is_LPG[6001];

int get_city_id(const string &city) {
  if (cities.find(city) == cities.end()) {
    int idx = cities.size();
    cities[city] = idx;
  }
  return cities[city];
}

class State {
public:
  int city_id;
  int dist;
  int remaining_LPG;
  State(int _city_id, int _dist, int _con) {
    city_id = _city_id;
    dist = _dist;
    remaining_LPG = _con;
  }

  bool operator<(const State &s) const { return (dist < s.dist); }

  bool operator>(const State &s) const { return (dist > s.dist); }
};

int main() {
  int total_roads;
  int total_LPG_stations;
  int capacity;
  while (~scanf("%d %d %d", &total_roads, &total_LPG_stations, &capacity)) {
    if (total_roads == 0 && total_LPG_stations == 0 && capacity == 0)
      break;

    cities.clear();

    vector<Node> nodes[6001];

    memset(is_LPG, false, sizeof(is_LPG));
    memset(dp, false, sizeof(dp));

    string src, dst;
    cin >> src >> dst;
    get_city_id(src);
    get_city_id(dst);

    for (int road_idx = 0; road_idx < total_roads; road_idx++) {
      string from_str, to_str;
      int dist;

      cin >> from_str >> to_str >> dist;
      int from_num = get_city_id(from_str);
      int to_num = get_city_id(to_str);

      nodes[from_num].push_back(Node(to_num, dist));
      nodes[to_num].push_back(Node(from_num, dist));
    }

    for (int LPG_idx = 0; LPG_idx < total_LPG_stations; LPG_idx++) {
      string city;
      cin >> city;
      is_LPG[get_city_id(city)] = true;
    }

    priority_queue<State, vector<State>, greater<State>> que;
    que.push(State(get_city_id(src), 0, 10 * capacity));
    dp[get_city_id(src)][10 * capacity] = true;

    int dst_id = get_city_id(dst);

    int res = INF;
    while (!que.empty()) {
      State s = que.top();
      que.pop();

      if (s.city_id == dst_id) {
        res = s.dist;
        goto found;
      }
      dp[s.city_id][s.remaining_LPG] = true;

      for (int to_idx = 0; to_idx < nodes[s.city_id].size(); to_idx++) {
        int to = nodes[s.city_id][to_idx].to;
        int dist = nodes[s.city_id][to_idx].dist;
        int next_remaining_LPG = s.remaining_LPG - dist;
        if (next_remaining_LPG < 0)
          continue;

        next_remaining_LPG =
            (is_LPG[to] ? 10 * capacity : s.remaining_LPG - dist);
        if (dp[to][next_remaining_LPG])
          continue;

        que.push(State(to, s.dist + dist, next_remaining_LPG));
      }
    }
  found:;
    printf("%d\\n", res >= INF ? -1 : res);
  }
  return 0;
}