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

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;

typedef vector<int> Array;
const int INF = 1e+8;

int main() {
  while (1) {
    int n, m, H, k;
    cin >> n >> m >> H >> k;
    if (!n)
      break;
    vector<tuple<int, int, int, int, int>> v;
    REP(i, m) {
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r;
      --a;
      --b;
      --r;
      v.emplace_back(a, b, c, h, r);
    }
    int s, t, p;
    cin >> s >> t >> p;
    --s;
    --t;
    Array cost1(1 << k);
    REP(i, 1 << k) {
      bitset<8> bs(i);
      Array ary(n * (H + 1), INF);
      ary[s * (H + 1)] = 0;
      REP(l, H + 1) {
        REP(j, m) {
          int a, b, c, h, r;
          tie(a, b, c, h, r) = v[j];
          if (l + h > H)
            continue;
          int ai = a * (H + 1), bi = b * (H + 1);
          if (bs[r]) {
            ary[ai + l + h] = min(ary[ai + l + h], ary[bi + l]);
            ary[bi + l + h] = min(ary[bi + l + h], ary[ai + l]);
          } else {
            ary[ai + l + h] = min(ary[ai + l + h], ary[bi + l] + c);
            ary[bi + l + h] = min(ary[bi + l + h], ary[ai + l] + c);
          }
        }
      }
      int minc = INF;
      REP(j, H + 1) minc = min(minc, ary[t * (H + 1) + j]);
      cost1[i] = minc;
    }
    Array cost2(1 << k, INF);
    cost2[0] = 0;
    REP(i, p) {
      Array tmp = cost2;
      int l, d;
      cin >> l >> d;
      int bits = 0;
      REP(j, l) {
        int kj;
        cin >> kj;
        --kj;
        bits |= 1 << kj;
      }
      REP(j, 1 << k)
      tmp[j | bits] = min(tmp[j | bits], cost2[j] + d);
      swap(tmp, cost2);
    }
    int minc = INF;
    REP(i, 1 << k) minc = min(minc, cost1[i] + cost2[i]);
    if (minc < INF)
      cout << minc << endl;
    else
      cout << -1 << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
typedef tuple<int, int, int, int, int> T;

typedef int Weight;
Weight INF = 1000000000;
struct Edge {
  int src, dest;
  Weight weight;
  bool operator<(const Edge &rhs) const { return weight > rhs.weight; }
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void add_edge(Graph &g, int src, int dest, Weight weight) {
  g[src].push_back((Edge){src, dest, weight});
}

bool SPFA(const Graph &g, Array &d, int s) {
  const int n = g.size();
  d.assign(n, INF);
  d[s] = 0;
  vector<int> updated(n, 0);
  vector<bool> inque(n, false);
  queue<int> que;
  que.push(s);
  while (!que.empty()) {
    int from = que.front();
    que.pop();
    inque[from] = false;
    updated[from]++;
    if (updated[from] == n)
      return false; // negative cycle
    for (Edge e : g[from]) {
      int to = e.dest;
      Weight cost = d[from] + e.weight;
      if (cost < d[to]) {
        d[to] = cost;
        if (!inque[to]) {
          que.push(to);
          inque[to] = true;
        }
      }
    }
  }
  return true;
}

int main() {
  while (1) {
    int n, m, H, k;
    cin >> n >> m >> H >> k;
    if (!n)
      break;
    vector<T> f(m);
    vector<tuple<int, int, int, int, int>> v;
    REP(i, m) {
      int a, b, c, h, r;
      cin >> a >> b >> c >> h >> r;
      --a;
      --b;
      --r;
      v.emplace_back(a, b, c, h, r);
    }
    int s, t, p;
    cin >> s >> t >> p;
    --s;
    --t;
    Array cost1(1 << k);
    REP(i, 1 << k) {
      bitset<8> bs(i);
      Graph g(n * (H + 1));
      REP(j, m) {
        int a, b, c, h, r;
        tie(a, b, c, h, r) = v[j];
        REP(l, H + 1) {
          if (l + h > H)
            break;
          if (bs[r]) {
            add_edge(g, a * (H + 1) + l, b * (H + 1) + l + h, 0);
            add_edge(g, b * (H + 1) + l, a * (H + 1) + l + h, 0);
          } else {
            add_edge(g, a * (H + 1) + l, b * (H + 1) + l + h, c);
            add_edge(g, b * (H + 1) + l, a * (H + 1) + l + h, c);
          }
        }
      }
      Array ary(n * (H + 1));
      SPFA(g, ary, s * (H + 1));
      int minc = INF;
      REP(j, H + 1) minc = min(minc, ary[t * (H + 1) + j]);
      cost1[i] = minc;
    }
    Array cost2(1 << k, INF);
    cost2[0] = 0;
    REP(i, p) {
      Array tmp = cost2;
      int l, d;
      cin >> l >> d;
      int bits = 0;
      REP(j, l) {
        int kj;
        cin >> kj;
        --kj;
        bits |= 1 << kj;
      }
      REP(j, 1 << k)
      tmp[j | bits] = min(tmp[j | bits], cost2[j] + d);
      swap(tmp, cost2);
    }
    int minc = INF;
    REP(i, 1 << k) minc = min(minc, cost1[i] + cost2[i]);
    if (minc < INF)
      cout << minc << endl;
    else
      cout << -1 << endl;
  }
  return 0;
}