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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vd = vector<double>;
using vvd = vector<vd>;

#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define ALL(c) (c).begin(), (c).end()
#define FOR(i, s, e) for (ll i = s; i < (ll)e; i++)
#define TEN(x) ((ll)1e##x)

template <class Edge, class State> struct dijkstra {
  using Cost = decltype(State{}.calc_cost(Edge{}));

  static vector<Cost> shortest_path(State s, const vector<vector<Edge>> &g,
                                    Cost max_dist) {
    vector<Cost> d(State::max_state_id() + 1, max_dist);
    d[s.state_id()] = 0;
    using P = pair<ll, State>;
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P(0, s));
    while (!que.empty()) {
      Cost cur_d;
      State cur;
      tie(cur_d, cur) = que.top();
      que.pop();
      auto v = cur.state_id();
      if (d[v] < cur_d)
        continue;
      for (auto e : g[cur.node_id])
        if (cur.is_valid(e)) {
          State next = cur.calc_next(e);
          auto u = next.state_id();
          if (d[u] > d[v] + cur.calc_cost(e)) {
            d[u] = d[v] + cur.calc_cost(e);
            que.push(P(d[u], next));
          }
        }
    }

    return d;
  }
};

struct Edge {
  ll to;
  ll cost;
  ll h;
  ll r;
};
struct State {
  static ll max_state_id() { return 5000; }
  bool operator<(const State &rhs) const { return node_id < rhs.node_id; }

  ll node_id;
  // more infomation
  ll h, passport; // passport = 2^8

  ll state_id() { return node_id + h * 100; }
  bool is_valid(Edge e) { return h + e.h < 25; }
  State calc_next(Edge e) { return State{e.to, e.h + h, passport}; }
  ll calc_cost(Edge e) {
    if ((passport & (1 << e.r)) != 0)
      return 0;
    return e.cost;
  }
};

int main() {
#ifdef INPUT_FROM_FILE
  ifstream cin("sample.in");
  ofstream cout("sample.out");
#endif
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(50);

  while (true) {
    ll n, m, H, K;
    cin >> n >> m >> H >> K;
    if (n == 0)
      break;
    vl a(m), b(m), c(m), h(m), r(m);
    REP(i, m) {
      cin >> a[i] >> b[i] >> c[i] >> h[i] >> r[i];
      a[i]--, b[i]--, r[i]--;
    }
    ll S, T;
    cin >> S >> T;
    S--, T--;
    ll P;
    cin >> P;
    vl l(P), d(P);
    vvl k(P);
    REP(i, P) {
      cin >> l[i] >> d[i];
      k[i].resize(l[i]);
      REP(j, l[i]) {
        cin >> k[i][j];
        k[i][j]--;
      }
    }

    vector<vector<Edge>> g(n);
    REP(i, m) {
      g[a[i]].push_back({b[i], c[i], h[i], r[i]});
      g[b[i]].push_back({a[i], c[i], h[i], r[i]});
    }

    ll max_dist = TEN(8);
    vl dp(1 << K, max_dist);
    dp[0] = 0;
    REP(i, P) {
      ll passport = 0;
      REP(j, l[i]) passport |= 1 << k[i][j];
      REP(j, 1 << K) dp[j | passport] = min(dp[j | passport], dp[j] + d[i]);
    }

    ll ans = max_dist;
    REP(passport, 1 << K) {
      auto dist =
          dijkstra<Edge, State>::shortest_path({S, 0, passport}, g, max_dist);
      REP(i, H + 1) if (dist[State{T, i, passport}.state_id()] != max_dist) {
        ans = min(ans, dp[passport] + dist[State{T, i, passport}.state_id()]);
      }
    }

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

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vd = vector<double>;
using vvd = vector<vd>;

#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define ALL(c) (c).begin(), (c).end()
#define FOR(i, s, e) for (ll i = s; i < (ll)e; i++)
#define TEN(x) ((ll)1e##x)

template <class Edge, class State> struct dijkstra {
  using Cost = decltype(State{}.calc_cost(Edge{}));

  static vector<Cost> shortest_path(State s, const vector<vector<Edge>> &g,
                                    Cost max_dist) {
    vector<Cost> d(State::max_state_id() + 1, max_dist);
    d[s.state_id()] = 0;
    using P = pair<ll, State>;
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P(0, s));
    while (!que.empty()) {
      Cost cur_d;
      State cur;
      tie(cur_d, cur) = que.top();
      que.pop();
      auto v = cur.state_id();
      if (d[v] < cur_d)
        continue;
      for (auto e : g[cur.node_id])
        if (cur.is_valid(e)) {
          State next = cur.calc_next(e);
          auto u = next.state_id();
          if (d[u] > d[v] + cur.calc_cost(e)) {
            d[u] = d[v] + cur.calc_cost(e);
            que.push(P(d[u], next));
          }
        }
    }

    return d;
  }
};

struct Edge {
  ll to;
  ll cost;
  ll h;
  ll r;
};
struct State {
  static ll max_state_id() { return TEN(7); }
  bool operator<(const State &rhs) const { return node_id < rhs.node_id; }

  ll node_id;
  // more infomation
  ll h, passport; // passport = 2^8

  ll state_id() { return node_id + h * 100; }
  bool is_valid(Edge e) { return h + e.h < 25; }
  State calc_next(Edge e) { return State{e.to, e.h + h, passport}; }
  ll calc_cost(Edge e) {
    if ((passport & (1 << e.r)) != 0)
      return 0;
    return e.cost;
  }
};

int main() {
#ifdef INPUT_FROM_FILE
  ifstream cin("sample.in");
  ofstream cout("sample.out");
#endif
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(50);

  while (true) {
    ll n, m, H, K;
    cin >> n >> m >> H >> K;
    if (n == 0)
      break;
    vl a(m), b(m), c(m), h(m), r(m);
    REP(i, m) {
      cin >> a[i] >> b[i] >> c[i] >> h[i] >> r[i];
      a[i]--, b[i]--, r[i]--;
    }
    ll S, T;
    cin >> S >> T;
    S--, T--;
    ll P;
    cin >> P;
    vl l(P), d(P);
    vvl k(P);
    REP(i, P) {
      cin >> l[i] >> d[i];
      k[i].resize(l[i]);
      REP(j, l[i]) {
        cin >> k[i][j];
        k[i][j]--;
      }
    }

    vector<vector<Edge>> g(n);
    REP(i, m) {
      g[a[i]].push_back({b[i], c[i], h[i], r[i]});
      g[b[i]].push_back({a[i], c[i], h[i], r[i]});
    }

    vl dp(1 << K, TEN(8));
    dp[0] = 0;
    REP(i, P) {
      ll passport = 0;
      REP(j, l[i]) passport |= 1 << k[i][j];
      REP(j, 1 << K) dp[j | passport] = min(dp[j | passport], dp[j] + d[i]);
    }

    ll max_dist = TEN(8);
    ll ans = max_dist;
    REP(passport, 1 << K) {
      auto dist =
          dijkstra<Edge, State>::shortest_path({S, 0, passport}, g, max_dist);
      REP(i, H + 1) if (dist[State{T, i, passport}.state_id()] != max_dist) {
        ans = min(ans, dp[passport] + dist[State{T, i, passport}.state_id()]);
      }
    }

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