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

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

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

int unit[20];
int need[20];

int nextInt() {
  int r = 0, ch;
  while (isspace(ch = getchar()))
    ;
  do {
    r = r * 10 + ch - '0';
  } while (isdigit(ch = getchar()));
  return r;
}

bool visited[1 << 20];

struct State {
  int one, mask, have;
  bool operator<(const State &t) const {
    if (one != t.one)
      return one > t.one;
    return have < t.have;
  }
};

int solve(int N, int U) {
  memset(visited, 0, sizeof(visited));
  priority_queue<State> up;
  State s;
  s.one = 0;
  s.mask = 0;
  s.have = 0;
  visited[s.mask] = 1;
  up.push(s);
  while (!up.empty()) {
    s = up.top();
    up.pop();

    if (s.have >= U)
      return s.one;

    for (int i = 0; i < N; i++)
      if (visited[s.mask | (1 << i)] == 0 && (s.mask | need[i]) == s.mask) {
        State next;
        next.mask = s.mask | (1 << i);
        next.one = s.one + 1;
        next.have = s.have + unit[i];
        visited[next.mask] = 1;
        up.push(next);
      }
  }
  return -1;
}

int main() {
  for (;;) {
    int N, U;
    N = nextInt();
    U = nextInt();
    if (N == 0 && U == 0)
      break;
    REP(i, N) need[i] = 0;

    int all = 0;
    REP(i, N) {
      unit[i] = nextInt();
      all += unit[i];
      int K = nextInt();
      REP(k, K) {
        int x = nextInt();
        need[i] |= (1 << x);
      }
    }
    if (all == U) {
      printf("%d\\n", N);
      continue;
    }
    int best = solve(N, U);
    printf("%d\\n", best);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

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

int unit[20];
int need[20];

int nextInt() {
  int r = 0, ch;
  while (isspace(ch = getchar()))
    ;
  do {
    r = r * 10 + ch - '0';
  } while (isdigit(ch = getchar()));
  return r;
}

bool visited[1 << 20];

struct State {
  int one, mask, have;
  bool operator<(const State &t) const {
    if (one != t.one)
      return one > t.one;
    return have < t.have;
  }
};

int solve(int N, int U) {
  memset(visited, 0, sizeof(visited));
  priority_queue<State> up;
  State s;
  s.one = 0;
  s.mask = 0;
  s.have = 0;
  visited[s.mask] = 1;
  up.push(s);
  while (!up.empty()) {
    s = up.top();
    up.pop();

    if (s.have >= U)
      return s.one;

    for (int i = 0; i < N; i++)
      if ((s.mask & (1 << i)) == 0 && (s.mask | need[i]) == s.mask) {
        State next;
        next.mask = s.mask | (1 << i);
        if (visited[next.mask])
          continue;
        next.one = s.one + 1;
        next.have = s.have + unit[i];
        visited[next.mask] = 1;
        up.push(next);
      }
  }
  return -1;
}

int main() {
  for (;;) {
    int N, U;
    N = nextInt();
    U = nextInt();
    if (N == 0 && U == 0)
      break;
    REP(i, N) need[i] = 0;

    REP(i, N) {
      unit[i] = nextInt();
      int K = nextInt();
      REP(k, K) {
        int x = nextInt();
        need[i] |= (1 << x);
      }
    }
    int best = solve(N, U);
    printf("%d\\n", best);
  }
}