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

#include <bits/stdc++.h>
using namespace std;

struct edge {
  int to, c, h, r;
};

struct node {
  int v, c, h;
  bool operator<(const node &u) const {
    if (c != u.c)
      return c > u.c;
    return h > u.h;
  }
};

int n, m, h, k, s, t, p;
int pass[256], done[128][32], ps[256];
vector<edge> G[128];

int dijkstra(int f, int ub) {
  priority_queue<node> q;
  q.push((node){s, pass[f], 0});
  memset(done, 0, sizeof(done));

  while (!q.empty()) {
    node u = q.top();
    q.pop();
    if (u.v == t or u.c >= ub)
      return u.c;
    if (done[u.v][u.h])
      continue;
    done[u.v][u.h] = 1;

    for (auto &e : G[u.v]) {
      if (u.h + e.h > h)
        continue;
      if (f & (1 << e.r))
        q.push((node){e.to, u.c, u.h + e.h});
      else
        q.push((node){e.to, u.c + e.c, u.h + e.h});
    }
  }
  return 1e9;
}

int solve() {
  pass[0] = 0;
  int ans = 1e9;
  for (int i = 0; i < 1 << k; i++) {
    if (pass[i] >= ans)
      continue;
    ans = min(ans, dijkstra(i, ans));
    for (int j = 0; j < p; j++) {
      pass[i | ps[j]] = min(pass[i | ps[j]], pass[i] + pass[ps[j]]);
    }
  }

  return ans < 1e9 ? ans : -1;
}

void init() {
  for (int i = 0; i < 128; i++)
    G[i].clear();
  fill(pass, pass + 256, 1e9);
}

bool input() {
  cin >> n >> m >> h >> k;
  if (!n)
    return 0;
  init();
  for (int i = 0; i < m; i++) {
    int a, b, c, h, r;
    cin >> a >> b >> c >> h >> r;
    --a;
    --b;
    --r;
    G[a].push_back((edge){b, c, h, r});
    G[b].push_back((edge){a, c, h, r});
  }
  cin >> s >> t >> p;
  --s;
  --t;
  for (int i = 0; i < p; i++) {
    int l, d, a, as = 0;
    cin >> l >> d;
    for (int j = 0; j < l; j++) {
      cin >> a;
      as |= 1 << (a - 1);
    }
    ps[i] = as;
    pass[as] = d;
  }
  return 1;
}

int main() {
  while (input())
    cout << solve() << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <stack>
using namespace std;
int n, m, h, k, p;
int C[100][100][10];
int G[100][100];
int T[100][100];
int bitcost[256];
int memo[100][25];

void dijk1() { // bitcost ??? dijkstra
  bitcost[0] = 0;
  for (int i = 0; i < 1 << k; ++i)
    for (int j = 0; j < 1 << k; ++j)
      bitcost[i | j] = min(bitcost[i | j], bitcost[i] + bitcost[j]);
}

void dijk2(int s) {
  bool used[100][25] = {};
  for (int i = 0; i <= 24; ++i)
    memo[s][i] = 0;
  while (true) {
    int id1 = -1, id2 = -1, m = 1 << 28;
    for (int i = 0; i < n; ++i)
      for (int j = 0; j <= 24; ++j)
        if (!used[i][j] && memo[i][j] < m) {
          m = memo[i][j];
          id1 = i;
          id2 = j;
        }
    if (id1 == -1 || id2 == -1)
      break;
    used[id1][id2] = true;
    for (int i = 0; i < n; ++i) {
      if (id2 + T[id1][i] > 24)
        continue;
      memo[i][id2 + T[id1][i]] =
          min(memo[i][id2 + T[id1][i]], memo[id1][id2] + G[id1][i]);
    }
  }
}

int main() {
  while (cin >> n >> m >> h >> k, n || m || h || k) {
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
        T[i][j] = 1 << 28;
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
        for (int l = 0; l < k; ++l)
          C[i][j][l] = 1 << 28;
    for (int i = 0; i < m; ++i) {
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r;
      a--;
      b--;
      r--;
      C[a][b][r] = C[b][a][r] = c;
      T[a][b] = T[b][a] = h;
    }
    int s, t;
    cin >> s >> t >> p;
    s--;
    t--;

    for (int i = 0; i < 1 << k; ++i)
      bitcost[i] = 1 << 28;
    for (int i = 0; i < p; ++i) {
      int l, d;
      cin >> l >> d;
      int b = 0;
      while (l--) {
        int x;
        cin >> x;
        x--;
        b |= 1 << x;
      }
      bitcost[b] = min(bitcost[b], d);
    }
    dijk1();
    int ans = 1 << 28;
    for (int bit = 0; bit < 1 << k; ++bit) {
      if (bitcost[bit] >= 1 << 28)
        continue;
      for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j) {
          G[i][j] = 1 << 28;
          G[i][i] = 0;
          for (int l = 0; l < k; ++l) {
            G[i][j] = min(G[i][j], C[i][j][l]);
            if ((bit >> l) & 1 && C[i][j][l] != 1 << 28)
              G[i][j] = 0;
          }
        }
      for (int i = 0; i < n; ++i)
        T[i][i] = 0;

      /*
      cout << bit << " " << bitcost[bit] << endl;
      for(int i=0;i<n;++i){
        for(int j=0;j<n;++j) cout << G[i][j] << " ";
        cout << endl;
      }
      */

      for (int i = 0; i < n; ++i)
        for (int j = 0; j <= 24; ++j)
          memo[i][j] = 1 << 28;
      dijk2(s);
      for (int i = 0; i <= h; ++i)
        ans = min(ans, bitcost[bit] + memo[t][i]);
    }
    if (ans == 1 << 28)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
  return 0;
}