Problem p01697 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)

#define X first
#define Y second

using namespace std;
typedef pair<int, int> pii;
const int INF = 1e9;

int main() {
  int N, M, H, K;
  while (cin >> N >> M >> H >> K, N | M | H | K) {
    vector<pii> edge[105];
    int cost[505], in_h[505], in_r[505];
    int S, T, P, pd[1 << 8], pk[1 << 8];
    fill(pd, pd + (1 << 8), INF);

    rep(i, M) {
      int a, b, c, h, r;
      cin >> a >> b >> cost[i] >> in_h[i] >> in_r[i];
      in_r[i]--;
      edge[a].emplace_back(b, i);
      edge[b].emplace_back(a, i);
    }
    cin >> S >> T >> P;
    rep(i, P) {
      int l, d, k, s = 0;
      cin >> l >> d;
      rep(j, l) {
        cin >> k;
        k--;
        s |= (1 << k);
      }
      pk[i] = s;
      pd[i] = d;
    }

    int pass[1 << 8];
    fill(pass, pass + (1 << 8), INF);
    pass[0] = 0;
    rep(i, 1 << K) rep(j, P) {
      pass[i | pk[j]] = min(pass[i | pk[j]], pass[i] + pd[j]);
    }
    // rep(i,1<<K) cout << pass[i] << " "; cout << endl;

    int ans = INF;
    rep(k, 1 << K) {
      if (pass[k] == INF)
        continue;
      int d[105][30];
      fill(d[0], d[0] + 105 * 30, ans - pass[k]);
      priority_queue<pair<int, pii>> que;
      d[S][0] = 0;
      que.push({0, {S, 0}});
      while (!que.empty()) {
        int dd = que.top().X;
        int dn = que.top().Y.X;
        int dh = que.top().Y.Y;
        que.pop();
        if (dd > d[dn][dh])
          continue;
        for (auto t : edge[dn]) {
          int nx = t.X;
          int nh = dh + in_h[t.Y];
          int ct = d[dn][dh];
          int r = in_r[t.Y];
          if (!((1 << r) & k))
            ct += cost[t.Y];
          if (nh <= H && ct < d[nx][nh]) {
            for (int i = nh; i <= H; i++)
              d[nx][i] = min(d[nx][i], ct);
            que.push({ct, {nx, nh}});
          }
        }
      }
      int ret = INF;
      rep(h, H + 1) ret = min(ret, d[T][h]);
      ans = min(ans, pass[k] + ret);
    }

    cout << (ans == INF ? -1 : ans) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)

#define X first
#define Y second

using namespace std;
typedef pair<int, int> pii;
const int INF = 1e9;

int main() {
  int N, M, H, K;
  while (cin >> N >> M >> H >> K, N | M | H | K) {
    vector<pii> edge[105];
    int cost[505], in_h[505], in_r[505];
    int S, T, P, pd[1 << 8], pk[1 << 8];
    fill(pd, pd + (1 << 8), INF);

    rep(i, M) {
      int a, b, c, h, r;
      cin >> a >> b >> cost[i] >> in_h[i] >> in_r[i];
      in_r[i]--;
      edge[a].emplace_back(b, i);
      edge[b].emplace_back(a, i);
    }
    cin >> S >> T >> P;
    rep(i, P) {
      int l, d, k, s = 0;
      cin >> l >> d;
      rep(j, l) {
        cin >> k;
        k--;
        s |= (1 << k);
      }
      pk[i] = s;
      pd[i] = d;
    }

    int pass[1 << 8];
    fill(pass, pass + (1 << 8), INF);
    pass[0] = 0;
    rep(i, 1 << K) rep(j, P) {
      pass[i | pk[j]] = min(pass[i | pk[j]], pass[i] + pd[j]);
    }
    // rep(i,1<<K) cout << pass[i] << " "; cout << endl;

    int ans = INF;
    rep(k, 1 << K) {
      if (pass[k] == INF)
        continue;
      int d[105][30];
      fill(d[0], d[0] + 105 * 30, ans);
      priority_queue<pair<int, pii>> que;
      d[S][0] = 0;
      que.push({0, {S, 0}});
      while (!que.empty()) {
        int dd = que.top().X;
        int dn = que.top().Y.X;
        int dh = que.top().Y.Y;
        que.pop();
        if (dd > d[dn][dh])
          continue;
        for (auto t : edge[dn]) {
          int nx = t.X;
          int nh = dh + in_h[t.Y];
          int ct = d[dn][dh];
          int r = in_r[t.Y];
          if (!((1 << r) & k))
            ct += cost[t.Y];
          if (nh <= H && ct < d[nx][nh]) {
            for (int i = nh; i <= H; i++)
              d[nx][i] = min(d[nx][i], ct);
            que.push({ct, {nx, nh}});
          }
        }
      }
      int ret = INF;
      rep(h, H + 1) ret = min(ret, d[T][h]);
      ans = min(ans, pass[k] + ret);
    }

    cout << (ans == INF ? -1 : ans) << endl;
  }
  return 0;
}