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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
const int maxm = 3001;
const int maxn = 3105;
const int INF = 0x3ffffff;
struct Side {
  int to, next, w;
} side[maxm * 2], side1[maxm * 2];
int node1[maxn * 2], top, top1, node[maxn];
void add_side(int u, int v, int w) {
  side[top] = (Side){v, node[u], w};
  node[u] = top++;
}

void add_side1(int u, int v, int w) {
  side1[top1] = (Side){v, node1[u], w};
  node1[u] = top1++;
  side1[top1] = (Side){u, node1[v], w};
  node1[v] = top1++;
}
int cap;
map<string, int> city;
int cnt1, cnt, start, end;
bool is1[maxn], is[maxn];
int get_id(string str) {
  if (city.count(str) == 0)
    city[str] = ++cnt1;
  return city[str];
}
int dis[maxn][2001];
bool inqueue[maxn][2001];
queue<pair<int, int>> q;
int get_dis() {
  for (int i = 1; i <= cnt; i++) {
    for (int j = 0; j <= cap; j++) {
      inqueue[i][j] = false;
      dis[i][j] = INF;
    }
  }
  dis[start][cap] = 0;
  pair<int, int> tmp = make_pair(start, cap);
  q.push(tmp);
  while (!q.empty()) {
    tmp = q.front();
    q.pop();
    int u = tmp.first;
    int c = tmp.second;
    inqueue[u][c] = false;
    if (c != cap && is[u]) {
      if (dis[u][c] < dis[u][cap]) {
        dis[u][cap] = dis[u][c];
        if (!inqueue[u][cap]) {
          inqueue[u][cap] = true;
          q.push(make_pair(u, cap));
        }
      }
    }
    for (int i = node[u]; i != -1; i = side[i].next) {
      int v = side[i].to;
      int last = c - side[i].w;
      if (last < 0)
        continue;
      if (dis[u][c] + side[i].w < dis[v][last]) {
        dis[v][last] = dis[u][c] + side[i].w;
        if (!inqueue[v][last]) {
          inqueue[v][last] = true;
          q.push(make_pair(v, last));
        }
      }
    }
  }
  int ans = INF;
  for (int i = 0; i <= cap; i++) {
    ans = min(ans, dis[end][i]);
  }
  return ans == INF ? -1 : ans;
}
bool vis[6001];
int id[maxn * 2];
void dfs(int u) {
  for (int i = node1[u]; i != -1; i = side1[i].next) {
    int v = side1[i].to;
    if (!vis[v]) {
      vis[v] = true;
      dfs(v);
    }
  }
}
int main() {
  int n, m;
  while (~scanf("%d%d%d", &m, &n, &cap)) {
    if (m == 0 && n == 0 && cap == 0)
      break;
    cap = cap * 10;
    city.clear();
    top = 0;
    cnt = 0;
    cnt1 = 0;
    top1 = 0;
    memset(node, -1, sizeof(node));
    memset(node1, -1, sizeof(node1));
    memset(is, false, sizeof(is));
    memset(is1, false, sizeof(is1));
    memset(vis, false, sizeof(vis));
    string u, v;
    cin >> u >> v;
    start = get_id(u);
    end = get_id(v);
    for (int i = 0; i < m; i++) {
      cin >> u >> v;
      int w;
      scanf("%d", &w);
      int x = get_id(u);
      int y = get_id(v);
      add_side1(x, y, w);
    }
    for (int i = 0; i < n; i++) {
      cin >> u;
      is1[get_id(u)] = true;
    }
    vis[start] = true;
    dfs(start);
    if (!vis[end])
      printf("-1\\n");
    else {
      for (int i = 1; i <= cnt1; i++) {
        if (!vis[i])
          continue;
        id[i] = ++cnt;
      }
      for (int u = 1; u <= cnt1; u++) {
        if (!vis[u])
          continue;
        for (int i = node1[u]; i != -1; i = side1[i].next) {
          int v = side1[i].to;
          if (!vis[v])
            continue;
          add_side(id[u], id[v], side1[i].w);
        }
      }
      for (int i = 1; i <= cnt1; i++) {
        if (vis[i] && is1[i])
          is[id[i]] = true;
      }
      start = id[start];
      end = id[end];
      printf("%d\\n", get_dis());
    }
  }
}


Error: 0

Fixed submission:

/*
 *    author:  gantheory
 *    created: 2018-07-19 23:18:57
 */
#pragma GCC optimize("O3")
#include <bits/stdc++.h>

using namespace std;

const int N = 6000 + 10;

template <class T> using MinHeap = priority_queue<T, vector<T>, greater<T>>;

int n, m, cap;
string src, dest;
vector<pair<int, int>> adj[N], adj2[3010];

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.setf(ios::fixed), cout.precision(9);
  while (cin >> n >> m >> cap) {
    if (n + m + cap == 0)
      break;

    cap *= 10;
    cin >> src >> dest;
    map<string, int> mp;
    mp[src] = mp.size(), mp[dest] = mp.size();
    for (int i = 0; i < n; ++i) {
      string foo, bar;
      int c;
      cin >> foo >> bar >> c;
      int u = (mp.count(foo) ? mp[foo] : mp[foo] = mp.size());
      int v = (mp.count(bar) ? mp[bar] : mp[bar] = mp.size());
      adj[u].emplace_back(v, c), adj[v].emplace_back(u, c);
    }
    vector<string> cand = {src, dest};
    for (int i = 0; i < m; ++i) {
      string s;
      cin >> s;
      cand.push_back(s);
    }

    map<int, int> reach;
    reach[mp[dest]] = reach.size();
    vector<bool> visit(mp.size(), false);
    queue<int> q;
    q.push(mp[src]);
    while (!q.empty()) {
      int now = q.front();
      q.pop();
      if (visit[now])
        continue;
      if (reach.count(now) == 0)
        reach[now] = reach.size();
      visit[now] = true;
      for (auto &p : adj[now])
        q.push(p.first);
    }
    for (int i = 0; i < (int)mp.size(); ++i) {
      if (reach.count(i) == 0)
        continue;
      for (auto &p : adj[i])
        adj2[reach[i]].emplace_back(reach[p.first], p.second);
    }
    for (int i = 0; i < (int)mp.size(); ++i)
      adj[i].clear();
    set<int> good;
    for (string &s : cand)
      if (mp.count(s) and reach.count(mp[s]))
        good.insert(reach[mp[s]]);
    cand.clear();

    int s = reach[mp[src]], t = reach[mp[dest]];
    mp.clear();
    vector<vector<int>> d(reach.size(), vector<int>(cap + 1, INT_MAX));
    vector<set<int>> visit2(reach.size(), set<int>());
    d[s][cap] = 0;
    MinHeap<pair<pair<int, int>, int>> hp;
    hp.push({{0, cap}, s});
    while (1) {
      int now = -1, now_cap = -1;
      while (!hp.empty() and visit2[now = hp.top().second].count(
                                 now_cap = hp.top().first.second))
        hp.pop();
      if (now == -1 or visit2[now].count(now_cap))
        break;
      visit2[now].insert(now_cap);
      for (auto &p : adj2[now]) {
        int child = p.first, w = p.second;
        if (now_cap - w >= 0) {
          int nxt_cap = (good.count(child) ? cap : now_cap - w);
          if (d[now][now_cap] + w < d[child][nxt_cap]) {
            d[child][nxt_cap] = d[now][now_cap] + w;
            hp.push({{d[child][nxt_cap], nxt_cap}, child});
          }
        }
      }
    }
    for (int i = 0; i < (int)reach.size(); ++i)
      adj2[i].clear();

    cout << (d[t][cap] == INT_MAX ? -1 : d[t][cap]) << '\\n';
  }
}