Problem p01697 (C++)

Buggy submission (status: Memory Limit Exceeded):
//=================================
// Created on: 2018/07/04 16:12:54
//=================================
#include <bits/stdc++.h>
using namespace std;
struct CostGraph {
  CostGraph(const int n) : V{n}, edge(n) {}
  void addEdge(const int from, const int to, const int cost, const int tim,
               const int label) {
    edge[from].push_back(Edge{from, to, cost, tim, label});
  }
  struct Edge {
    Edge(const int from, const int to, const int cost, const int tim,
         const int label)
        : from{from}, to{to}, cost{cost}, tim{tim}, label{label} {}
    const int from, to, cost, tim, label;
  };
  const int V;
  vector<vector<Edge>> edge;
};
int main() {
  for (int N, M, H, K, S, T, P;;) {
    cin >> N >> M >> H >> K;
    if (N == 0 and M == 0 and H == 0 and K == 0) {
      break;
    }
    CostGraph g(N);
    for (int i = 0, a, b, c, h, r; i < M; i++) {
      cin >> a >> b >> c >> h >> r;
      a--, b--, r--;
      g.addEdge(a, b, c, h, r), g.addEdge(b, a, c, h, r);
    }
    cin >> S >> T >> P;
    S--, T--;
    using pii = pair<int, int>;
    vector<pii> pass(P);
    for (int i = 0, l; i < P; i++) {
      cin >> l >> pass[i].first;
      for (int j = 0, k; j < l; j++) {
        cin >> k, pass[i].second |= (1 << (k - 1));
      }
    }
    constexpr int INF = 1 << 28;
    const int MASK = 1 << K;
    vector<int> ans(MASK, INF);
    for (int mask = 0; mask < MASK; mask++) {
      using PP = pair<int, pii>;
      vector<vector<int>> d(N, vector<int>(H + 1, INF));
      priority_queue<PP, vector<PP>, greater<PP>> q;
      d[S][0] = 0, q.push({0, {S, 0}});
      while (not q.empty()) {
        const auto p = q.top();
        q.pop();
        const int cost = p.first, s = p.second.first, t = p.second.second;
        if (cost > d[s][t]) {
          continue;
        }
        for (const auto &e : g.edge[s]) {
          const int dh = e.tim, l = e.label,
                    dc = ((mask & (1 << l)) ? 0 : e.cost);
          if (t + dh > H) {
            continue;
          }
          if (d[e.to][t + dh] < cost + dc) {
            continue;
          }
          d[e.to][t + dh] = cost + dc, q.push({cost + dc, {e.to, t + dh}});
        }
      }
      for (int i = 0; i <= H; i++) {
        ans[mask] = min(ans[mask], d[T][i]);
      }
    }
    vector<int> dp(MASK, INF);
    dp[0] = 0;
    for (int i = 0; i < P; i++) {
      auto tmp = dp;
      const int mask = pass[i].second;
      for (int num = mask; num > 0; num = (num - 1) & mask) {
        for (int j = 0; j < MASK; j++) {
          if (dp[j] == INF) {
            continue;
          }
          int newmask = j;
          for (int k = 1; k < MASK; k <<= 1) {
            if ((num & k) == 0) {
              continue;
            }
            newmask |= k;
          }
          tmp[newmask] = min(tmp[newmask], dp[j] + pass[i].first);
        }
      }
      dp = tmp;
    }
    int answer = INF;
    for (int i = 0; i < MASK; i++) {
      answer = min(answer, ans[i] + dp[i]);
    }
    cout << (answer == INF ? -1 : answer) << endl;
  }
  return 0;
}


Fixed submission:
//=================================
// Created on: 2018/07/04 16:12:54
//=================================
#include <bits/stdc++.h>
using namespace std;
struct CostGraph {
  CostGraph(const int n) : V{n}, edge(n) {}
  void addEdge(const int from, const int to, const int cost, const int tim,
               const int label) {
    edge[from].push_back(Edge{from, to, cost, tim, label});
  }
  struct Edge {
    Edge(const int from, const int to, const int cost, const int tim,
         const int label)
        : from{from}, to{to}, cost{cost}, tim{tim}, label{label} {}
    const int from, to, cost, tim, label;
  };
  const int V;
  vector<vector<Edge>> edge;
};
int main() {
  for (int N, M, H, K, S, T, P;;) {
    cin >> N >> M >> H >> K;
    if (N == 0 and M == 0 and H == 0 and K == 0) {
      break;
    }
    CostGraph g(N);
    for (int i = 0, a, b, c, h, r; i < M; i++) {
      cin >> a >> b >> c >> h >> r;
      a--, b--, r--;
      g.addEdge(a, b, c, h, r), g.addEdge(b, a, c, h, r);
    }
    cin >> S >> T >> P;
    S--, T--;
    using pii = pair<int, int>;
    vector<pii> pass(P);
    for (int i = 0, l; i < P; i++) {
      cin >> l >> pass[i].first;
      for (int j = 0, k; j < l; j++) {
        cin >> k, pass[i].second |= (1 << (k - 1));
      }
    }
    constexpr int INF = 1 << 28;
    const int MASK = 1 << K;
    vector<int> ans(MASK, INF);
    for (int mask = 0; mask < MASK; mask++) {
      using PP = pair<int, pii>;
      vector<vector<int>> d(N, vector<int>(H + 1, INF));
      priority_queue<PP, vector<PP>, greater<PP>> q;
      d[S][0] = 0, q.push({0, {S, 0}});
      while (not q.empty()) {
        const auto p = q.top();
        q.pop();
        const int cost = p.first, s = p.second.first, t = p.second.second;
        if (cost > d[s][t]) {
          continue;
        }
        for (const auto &e : g.edge[s]) {
          const int dh = e.tim, l = e.label,
                    dc = ((mask & (1 << l)) ? 0 : e.cost);
          if (t + dh > H) {
            continue;
          }
          if (d[e.to][t + dh] <= cost + dc) {
            continue;
          }
          d[e.to][t + dh] = cost + dc, q.push({cost + dc, {e.to, t + dh}});
        }
      }
      for (int i = 0; i <= H; i++) {
        ans[mask] = min(ans[mask], d[T][i]);
      }
    }
    vector<int> dp(MASK, INF);
    dp[0] = 0;
    for (int i = 0; i < P; i++) {
      auto tmp = dp;
      const int mask = pass[i].second;
      for (int num = mask; num > 0; num = (num - 1) & mask) {
        for (int j = 0; j < MASK; j++) {
          if (dp[j] == INF) {
            continue;
          }
          int newmask = j;
          for (int k = 1; k < MASK; k <<= 1) {
            if ((num & k) == 0) {
              continue;
            }
            newmask |= k;
          }
          tmp[newmask] = min(tmp[newmask], dp[j] + pass[i].first);
        }
      }
      dp = tmp;
    }
    int answer = INF;
    for (int i = 0; i < MASK; i++) {
      answer = min(answer, ans[i] + dp[i]);
    }
    cout << (answer == INF ? -1 : answer) << endl;
  }
  return 0;
}