Problem p00897 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <vector> // container

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(), (c).end()
#define FOR(i, l, r) for (int i = (int)l; i < (int)r; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORr(i, l, r) for (int i = (int)r - 1; i >= (int)l; --i)
#define REPr(i, n) FORr(i, 0, n)
#define EACH(i, c)                                                             \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

template <typename T, typename U> T pmod(T x, U M) { return (x % M + M) % M; }

typedef long long ll;

// output
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  os << get<0>(t);
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  os << get<0>(t) << " " << get<1>(t);
  return os;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t) << " " << get<6>(t);
  return os;
}

typedef int Cost;
Cost CINF = 1 << 28;
struct Edge {
  int f, t;
  Cost c;
  Edge(int f, int t, Cost c) : f(f), t(t), c(c){};
  bool operator<(Edge r) const { return c < r.c; }
  bool operator>(Edge r) const { return c > r.c; }
};
typedef vector<vector<Edge>> Graph;

struct Task {
  int prev, pos;
  Cost c;
  Task(int prev, int pos, Cost c) : prev(prev), pos(pos), c(c){};
  bool operator>(const Task &r) const { return c > r.c; }
};

vector<Cost> dijkstra(const Graph &g, const int s, vector<int> &prev) {
  const int V = g.size();
  vector<Cost> d(V, CINF);
  d[s] = 0;
  fill(ALL(prev), -2);

  priority_queue<Task, vector<Task>, greater<Task>> que;
  que.push(Task(-1, s, 0)); // [ ,e,,f, ] <=> e.cost < e.cost
  vector<bool> visited(V);
  while (!que.empty()) {
    Task task = que.top();
    que.pop();
    if (visited[task.pos])
      continue;
    visited[task.pos] = true;
    prev[task.pos] = task.prev;
    EACH(e, g[task.pos]) if (d[e->t] > d[e->f] + e->c) {
      d[e->t] = d[e->f] + e->c;
      que.push(Task(e->f, e->t, d[e->t]));
    }
  }
  return d;
}
vector<Cost> dijkstra(const Graph &g, const int s) {
  vector<int> prev(g.size());
  return dijkstra(g, s, prev);
}

int main() {
  cout << fixed << setprecision(15);
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (true) {
    int N, M, cap;
    cin >> N >> M >> cap;
    if (N == 0)
      break;

    map<string, int> m;
    int S = 0;
    int s;
    {
      string src;
      cin >> src;
      if (!m.count(src))
        m[src] = s = S++;
    }
    int t;
    {
      string dist;
      cin >> dist;
      if (!m.count(dist))
        m[dist] = t = S++;
    }
    vector<tuple<int, int, int>> es;
    REP(i, N) {
      string f, t;
      int c;
      cin >> f >> t >> c;
      if (!m.count(f))
        m[f] = S++;
      if (!m.count(t))
        m[t] = S++;
      es.emplace_back(m[f], m[t], c);
    }
    vector<int> ss;
    REP(i, M) {
      string s;
      cin >> s;
      if (!m.count(s))
        m[s] = S++;
      ss.push_back(m[s]);
    }
    map<int, int> stoi;
    int I = 0;
    if (!stoi.count(s))
      stoi[s] = I++;
    if (!stoi.count(t))
      stoi[t] = I++;
    REP(i, M) if (!stoi.count(ss[i])) { stoi[ss[i]] = I++; }
    map<int, int> itoS;
    EACH(it, stoi) itoS[it->second] = it->first;

    Graph g(S);
    REP(i, N) {
      cerr << es[i] << endl;
      g[get<0>(es[i])].emplace_back(get<0>(es[i]), get<1>(es[i]),
                                    get<2>(es[i]));
      g[get<1>(es[i])].emplace_back(get<1>(es[i]), get<0>(es[i]),
                                    get<2>(es[i]));
    }
    Graph gc(I);
    REP(i, I) {
      vector<Cost> cs = dijkstra(g, itoS[i]);
      REP(j, S) if (stoi.count(j)) {
        int ji = stoi[j];
        if (cs[j] <= 10 * cap)
          gc[i].emplace_back(i, ji, cs[j]);
      }
    }
    vector<Cost> cs = dijkstra(gc, s);

    if (cs[t] >= CINF)
      cout << -1 << endl;
    else
      cout << cs[t] << endl;
  }
}

Fixed submission:
#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <vector> // container

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(), (c).end()
#define FOR(i, l, r) for (int i = (int)l; i < (int)r; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORr(i, l, r) for (int i = (int)r - 1; i >= (int)l; --i)
#define REPr(i, n) FORr(i, 0, n)
#define EACH(i, c)                                                             \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

template <typename T, typename U> T pmod(T x, U M) { return (x % M + M) % M; }

typedef long long ll;

// output
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  REP(i, as.size()) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  os << get<0>(t);
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  os << get<0>(t) << " " << get<1>(t);
  return os;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t);
  return os;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t)
     << " " << get<4>(t) << " " << get<5>(t) << " " << get<6>(t);
  return os;
}

typedef int Cost;
Cost CINF = 1 << 28;
struct Edge {
  int f, t;
  Cost c;
  Edge(int f, int t, Cost c) : f(f), t(t), c(c){};
  bool operator<(Edge r) const { return c < r.c; }
  bool operator>(Edge r) const { return c > r.c; }
};
typedef vector<vector<Edge>> Graph;

struct Task {
  int prev, pos;
  Cost c;
  Task(int prev, int pos, Cost c) : prev(prev), pos(pos), c(c){};
  bool operator>(const Task &r) const { return c > r.c; }
};

vector<Cost> dijkstra(const Graph &g, const int s, vector<int> &prev) {
  const int V = g.size();
  vector<Cost> d(V, CINF);
  d[s] = 0;
  fill(ALL(prev), -2);

  priority_queue<Task, vector<Task>, greater<Task>> que;
  que.push(Task(-1, s, 0)); // [ ,e,,f, ] <=> e.cost < e.cost
  vector<bool> visited(V);
  while (!que.empty()) {
    Task task = que.top();
    que.pop();
    if (visited[task.pos])
      continue;
    visited[task.pos] = true;
    prev[task.pos] = task.prev;
    EACH(e, g[task.pos]) if (d[e->t] > d[e->f] + e->c) {
      d[e->t] = d[e->f] + e->c;
      que.push(Task(e->f, e->t, d[e->t]));
    }
  }
  return d;
}
vector<Cost> dijkstra(const Graph &g, const int s) {
  vector<int> prev(g.size());
  return dijkstra(g, s, prev);
}

int main() {
  cout << fixed << setprecision(15);
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (true) {
    int N, M, cap;
    cin >> N >> M >> cap;
    if (N == 0)
      break;

    map<string, int> m;
    int S = 0;
    int s;
    {
      string src;
      cin >> src;
      if (!m.count(src))
        m[src] = s = S++;
    }
    int t;
    {
      string dist;
      cin >> dist;
      if (!m.count(dist))
        m[dist] = t = S++;
    }
    vector<tuple<int, int, int>> es;
    REP(i, N) {
      string f, t;
      int c;
      cin >> f >> t >> c;
      if (!m.count(f))
        m[f] = S++;
      if (!m.count(t))
        m[t] = S++;
      es.emplace_back(m[f], m[t], c);
    }
    vector<int> ss;
    REP(i, M) {
      string s;
      cin >> s;
      if (!m.count(s))
        m[s] = S++;
      ss.push_back(m[s]);
    }
    map<int, int> stoi;
    int I = 0;
    if (!stoi.count(s))
      stoi[s] = I++;
    if (!stoi.count(t))
      stoi[t] = I++;
    REP(i, M) if (!stoi.count(ss[i])) { stoi[ss[i]] = I++; }
    map<int, int> itoS;
    EACH(it, stoi) itoS[it->second] = it->first;

    Graph g(S);
    REP(i, N) {
      // cerr << es[i] <<endl;
      g[get<0>(es[i])].emplace_back(get<0>(es[i]), get<1>(es[i]),
                                    get<2>(es[i]));
      g[get<1>(es[i])].emplace_back(get<1>(es[i]), get<0>(es[i]),
                                    get<2>(es[i]));
    }
    Graph gc(I);
    REP(i, I) {
      vector<Cost> cs = dijkstra(g, itoS[i]);
      REP(j, S) if (stoi.count(j)) {
        int ji = stoi[j];
        if (cs[j] <= 10 * cap)
          gc[i].emplace_back(i, ji, cs[j]);
      }
    }
    vector<Cost> cs = dijkstra(gc, s);

    if (cs[t] >= CINF)
      cout << -1 << endl;
    else
      cout << cs[t] << endl;
  }
}