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

#include <algorithm>
#include <climits>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct Tag {
  int pos, pat, cost;
  Tag() : pos(0), pat(0), cost(0) {}
  Tag(int p, int pat, int c) : pos(p), pat(pat), cost(c) {}
  bool operator<(const Tag &other) const { return cost > other.cost; }
};

struct Dict {
  map<string, int> dict;
  int id;

  Dict() : id(0) {}

  int get(const string &str) {
    if (dict.count(str))
      return dict[str];
    return dict[str] = id++;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  while (true) {
    int N;
    cin >> N;
    if (!N)
      break;

    map<string, int> best_price;
    vector<map<string, int>> store(N + 1);
    for (int i = 1; i <= N; ++i) {
      int K;
      cin >> K;
      while (K--) {
        string name;
        int price;
        cin >> name >> price;
        store[i][name] = price;
        if (best_price.count(name) == 0 || best_price[name] > price) {
          best_price[name] = price;
        }
      }
    }
    int Q;
    cin >> Q;
    bool impossible = false;
    int ans_value = 0;
    vector<int> mask(N + 1, 0);
    Dict dict;
    for (int i = 0; i < Q; ++i) {
      string name;
      cin >> name;
      if (best_price.count(name) == 0) {
        impossible = true;
      }
      const int id = dict.get(name);
      ans_value += best_price[name];
      for (int j = 1; j <= N; ++j) {
        if (store[j].count(name) && store[j][name] == best_price[name]) {
          mask[j] |= (1 << id);
        }
      }
    }
    int M;
    cin >> M;
    vector<vector<pair<int, int>>> road(N + 1);
    while (M--) {
      int S, T, D;
      cin >> S >> T >> D;
      road[S].push_back(make_pair(T, D));
      road[T].push_back(make_pair(S, D));
    }

    if (impossible) {
      cout << "impossible" << endl;
    } else {
      ++N;
      vector<vector<int>> memo(N, vector<int>(1 << Q, INT_MAX));
      priority_queue<Tag> q;
      q.push(Tag(0, 0, 0));
      while (!q.empty()) {
        const Tag t = q.top();
        q.pop();
        if (memo[t.pos][t.pat] < t.cost)
          continue;
        memo[t.pos][t.pat] = t.cost;
        if (t.pos == 0 && t.pat == (1 << Q) - 1)
          break;

        for (vector<pair<int, int>>::const_iterator it = road[t.pos].begin();
             it != road[t.pos].end(); ++it) {
          const int npos = it->first;
          const int npat = t.pat | mask[npos];
          const int ncost = t.cost + it->second;
          if (memo[npos][npat] > ncost) {
            memo[npos][npat] = ncost;
            q.push(Tag(npos, npat, ncost));
          }
        }
      }
      cout << ans_value << ' ' << memo[0][(1 << Q) - 1] << endl;
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <climits>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

using namespace std;

struct Tag {
  int pos, pat, cost;
  Tag() : pos(0), pat(0), cost(0) {}
  Tag(int p, int pat, int c) : pos(p), pat(pat), cost(c) {}
  bool operator<(const Tag &other) const { return cost > other.cost; }
};

struct Dict {
  map<string, int> dict;
  int id;

  Dict() : id(0) {}

  int get(const string &str) {
    if (dict.count(str))
      return dict[str];
    return dict[str] = id++;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  while (true) {
    int N;
    cin >> N;
    if (!N)
      break;

    map<string, int> best_price;
    vector<map<string, int>> store(N + 1);
    for (int i = 1; i <= N; ++i) {
      int K;
      cin >> K;
      while (K--) {
        string name;
        int price;
        cin >> name >> price;
        store[i][name] = price;
        if (best_price.count(name) == 0 || best_price[name] > price) {
          best_price[name] = price;
        }
      }
    }
    int Q;
    cin >> Q;
    bool impossible = false;
    int ans_value = 0;
    vector<int> mask(N + 1, 0);
    Dict dict;
    for (int i = 0; i < Q; ++i) {
      string name;
      cin >> name;
      if (best_price.count(name) == 0) {
        impossible = true;
      }
      const int id = dict.get(name);
      ans_value += best_price[name];
      for (int j = 1; j <= N; ++j) {
        if (store[j].count(name) && store[j][name] == best_price[name]) {
          mask[j] |= (1 << id);
        }
      }
    }
    int M;
    cin >> M;
    vector<vector<pair<int, int>>> road(N + 1);
    while (M--) {
      int S, T, D;
      cin >> S >> T >> D;
      road[S].push_back(make_pair(T, D));
      road[T].push_back(make_pair(S, D));
    }

    if (impossible) {
      cout << "impossible" << endl;
    } else {
      ++N;
      vector<vector<int>> memo(N, vector<int>(1 << N, INT_MAX));
      priority_queue<Tag> q;
      q.push(Tag(0, 0, 0));
      while (!q.empty()) {
        Tag t = q.top();
        q.pop();
        if (memo[t.pos][t.pat] < t.cost)
          continue;
        memo[t.pos][t.pat] = t.cost;
        if (t.pos == 0 && t.pat == (1 << Q) - 1)
          break;

        for (vector<pair<int, int>>::const_iterator it = road[t.pos].begin();
             it != road[t.pos].end(); ++it) {
          const int npos = it->first;
          const int npat = t.pat | mask[npos];
          const int ncost = t.cost + it->second;
          if (memo[npos][npat] > ncost) {
            memo[npos][npat] = ncost;
            q.push(Tag(npos, npat, ncost));
          }
        }
      }
      cout << ans_value << ' ' << memo[0][(1 << Q) - 1] << endl;
    }
  }
  return 0;
}