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

#include <algorithm>
#include <climits>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

const int MAX_V = 108;
const int H = 106;
const int D = 107;

int m, n, k, d, calorie[6];

struct Edge {
  int to, cost, cakeFlag;
};
vector<Edge> G[MAX_V];

int dist[64][108];

int toInt(string s) {
  stringstream ss(s);
  int ret = 0;
  ss >> ret;
  return ret;
}

int makeKey(string s) {
  if (s[0] == 'C')
    return toInt(s.substr(1)) - 1;
  if (s[0] == 'L')
    return toInt(s.substr(1)) + 5;
  if (s == "H")
    return H;
  return D;
}

void addEdge(string a, string b, int cost) {
  int ak = makeKey(a);
  int bk = makeKey(b);
  if (b[0] == 'C') {
    G[ak].push_back((Edge){bk, cost - calorie[bk], 1 << bk});
  } else {
    G[ak].push_back((Edge){bk, cost, 0});
  }
  if (a[0] == 'C') {
    G[bk].push_back((Edge){ak, cost - calorie[ak], 1 << ak});
  } else {
    G[bk].push_back((Edge){ak, cost, 0});
  }
}

int shortestPath(int from, int to) {
  for (int i = 0; i < 64; ++i) {
    for (int j = 0; j < 108; ++j) {
      dist[i][j] = INT_MAX;
    }
  }
  dist[0][from] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(from, 0));
  while (!q.empty()) {
    int now = q.front().first;
    int flag = q.front().second;
    q.pop();
    for (int i = 0; i < (int)G[now].size(); ++i) {
      Edge &e = G[now][i];
      if (flag & e.cakeFlag)
        continue;
      if (dist[flag][now] + e.cost < dist[flag | e.cakeFlag][e.to]) {
        dist[flag | e.cakeFlag][e.to] = dist[flag][now] + e.cost;
        q.push(make_pair(e.to, flag | e.cakeFlag));
      }
    }
  }
  int ret = INT_MAX;
  for (int i = 0; i < 64; ++i) {
    ret = min(ret, dist[i][to]);
  }
  return ret;
}

int main() {
  while (cin >> m >> n >> k >> d, m) {
    fill(G, G + MAX_V, vector<Edge>());
    for (int i = 0; i < m; ++i) {
      cin >> calorie[i];
    }
    string a, b;
    int cost;
    for (int i = 0; i < d; ++i) {
      cin >> a >> b >> cost;
      addEdge(a, b, cost * k);
    }
    cout << shortestPath(H, D) << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

const int MAX_V = 108;
const int H = 106;
const int D = 107;

int m, n, k, d, calorie[6];

struct Edge {
  int to, cost, cakeFlag;
};
vector<Edge> G[MAX_V];

int dist[32][108];

int toInt(string s) {
  stringstream ss(s);
  int ret = 0;
  ss >> ret;
  return ret;
}

int makeKey(string s) {
  if (s[0] == 'C')
    return toInt(s.substr(1)) - 1;
  if (s[0] == 'L')
    return toInt(s.substr(1)) + 5;
  if (s == "H")
    return H;
  return D;
}

void addEdge(string a, string b, int cost) {
  int ak = makeKey(a);
  int bk = makeKey(b);
  if (b[0] == 'C') {
    G[ak].push_back((Edge){bk, cost - calorie[bk], 1 << bk});
  } else {
    G[ak].push_back((Edge){bk, cost, 0});
  }
  if (a[0] == 'C') {
    G[bk].push_back((Edge){ak, cost - calorie[ak], 1 << ak});
  } else {
    G[bk].push_back((Edge){ak, cost, 0});
  }
}

int shortestPath(int from, int to) {
  for (int i = 0; i < 32; ++i) {
    for (int j = 0; j < 108; ++j) {
      dist[i][j] = INT_MAX;
    }
  }
  dist[0][from] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(from, 0));
  while (!q.empty()) {
    int now = q.front().first;
    int flag = q.front().second;
    q.pop();
    for (int i = 0; i < (int)G[now].size(); ++i) {
      Edge &e = G[now][i];
      if (flag & e.cakeFlag)
        continue;
      if (dist[flag][now] + e.cost < dist[flag | e.cakeFlag][e.to]) {
        dist[flag | e.cakeFlag][e.to] = dist[flag][now] + e.cost;
        q.push(make_pair(e.to, flag | e.cakeFlag));
      }
    }
  }
  int ret = INT_MAX;
  for (int i = 0; i < 32; ++i) {
    ret = min(ret, dist[i][to]);
  }
  return ret;
}

int main() {
  while (cin >> m >> n >> k >> d, m) {
    fill(G, G + MAX_V, vector<Edge>());
    for (int i = 0; i < m; ++i) {
      cin >> calorie[i];
    }
    string a, b;
    int cost;
    for (int i = 0; i < d; ++i) {
      cin >> a >> b >> cost;
      addEdge(a, b, cost * k);
    }
    cout << shortestPath(H, D) << endl;
  }
  return 0;
}