Problem:
Problem D:
Course Planning for Lazy Students
会津大学では2009年度より、授業履修に関する新しい制度を開始した。新制度では必修科目を撤廃し、それぞれの進路を考慮して科目を自由に選択できるようになった。
しかし、どの科目も無条件で履修できるわけではなく、特定の科目を履修するためには、先修条件を満たしている必要がある。下図に履修計画表の一部の例を示す：
図の長方形が１つの科目を表し科目名と単位数を含んでいる。図の矢印が先修条件を表す。矢印の意味は、矢印の終点で指されている科目を履修するためには、その矢印の始点を示す科目を修得している必要がある。例えば、Linear Algebra II (線形代数２)を履修するためには、Linear Algebra I (線形代数１)を修得している必要がある。また、Applied Algebra (応用代数)を履修するためには、Linear Algebra I と Discrete Systems (離散系論)の両方を修得している必要がある。
さて、履修登録計画において卒業に要する最低限の合計単位数
U
を満たす履修科目の組み合わせは、怠慢な学生にとって興味深いものである。
あなたの仕事は、与えられた履修計画表と
U
を読み込み、最低限の履修科目数を報告するプログラムを作成することである。これは計画であるため、履修登録した科目は必ず単位を修得できるものと仮定する。
Input
入力は複数のデータセットからなる。各データセットは以下の形式で与えられる：
n
U
c
0
k
0
r
0
1
r
0
2
...
r
0
k
0
c
1
k
1
r
1
1
r
1
2
...
r
1
k
1
.
.
c
n-1
k
n-1
r(n-1)
1
r(n-1)
2
...
r(n-1)
k
n-1
n
(1 ≤
n
≤ 20) は履修計画表が含む科目の数を示す整数である。科目には 0 から
n
-1 までの番号が割り当てられているものとし、以下
i
番目の科目を科目
i
と呼ぶことにする。
U
(1 ≤
U
≤ 100) は必要な合計単位数を表す整数である。
c
i
(1 ≤
c
i
≤ 10)は科目
i
の単位数を示す。次の
k
i
(0 ≤
k
i
≤ 5) は科目
i
の先修科目の数を示す。それに続く
ri
1
ri
2
...
ri
k
i
は科目
i
の先修科目の科目番号を示す。
ある科目から先修条件を表す矢印を１つ以上たどり、再びその科目に戻るような入力は与えられない。また、
U
を満たす科目の組み合わせが必ず存在すると仮定してよい。
n
と
U
がともに 0 のとき入力の終わりを示す。データセットの数は 100 を超えない。
Output
各データセットについて、最低限必要な科目数を１行に出力せよ。
Sample Input
4 4
1 0
3 2 0 2
2 0
2 0
3 6
1 0
3 2 0 2
2 0
0 0
Output for the Sample Input
2
3

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <list>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
#include <cassert>
#include <random>
#include<iostream>
#include<cmath>


struct Subject {
	int point{ 0 }, need{ 0 };
};

int main() {
	std::vector<std::vector<int>> by_digit(21);
	for (auto i = 0; i < (1 << 20); ++i) {
		int count = 0;
		for (auto j = i; j > 0; j >>= 1) {
			count += j % 2;
		}
		by_digit[count].push_back(i);
	}
	while (true) {
		int n, u; std::cin >> n >> u; if (n == 0) break;
		std::vector<Subject> subjects(n);
		for (auto &s: subjects) {
			int prev;
			std::cin >> s.point >> prev;
			for (auto i = 0; i < prev; ++i) {
				int a; std::cin >> a;
				s.need |= (1 << a);
			}
		}
		int min_count = -1;
		for (auto d = 1; min_count == -1; ++d) {
			for (const auto p : by_digit[d]) {
				int point = 0;
				for (auto i = 0; i < subjects.size(); ++i) if ((p & (1 << i)) != 0) {
					if ((p & (subjects[i].need)) != subjects[i].need) {
						point = 0;
						break;
					}
					else {
						point += subjects[i].point;
					}
				}
				if (point >= u) {
					min_count = d;
					break;
				}
			}
		}
		std::cout << min_count << '\n';
	}
}
accuracy: 1
time_ms: 460
memory_kb: 7572
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;

int main(){
    int n, u;
    while(cin >> n >> u, n+u){
        vector<int> c(n), p(n);
        for(int i = 0; i < n; i++){
            cin >> c[i];
            int k;  cin >> k;
            while(k-- > 0){
                int r;  cin >> r;
                p[i] |= (1<<r);
            }
        }
        
        auto popcnt = [](int x)->int{
            int ret = 0;
            while(x > 0){
                ret += x&1;
                x >>= 1;
            }
            return ret;
        };

        int ans = 21;
        queue<pair<int,int>> q;
        vector<bool> visit(1<<n, 0);
        q.push({0, 0});
        while(!q.empty()){
            pair<int,int> x = q.front();    q.pop();
            int bit = x.first, score = x.second;
            if(visit[bit])  continue;
            visit[bit] = true;
            if(score >= u){
                ans = min(ans, popcnt(bit));
                continue;
            }
            for(int i = 0; i < n; i++){
                if( ((bit>>i)&1) == 1 || (p[i]&bit) != p[i] || visit[bit|(1<<i)])    continue;
                q.push({bit|(1<<i), score+c[i]});
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 19444
final_rank: 19

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld =long double;
const ld eps = 1e-9;

bool solve(bitset<18>bs, vector<vector<int>>&dp,const vector<pair<int,int>>&vs,const int now) {
	if(dp[now][bs.to_ulong()]!=-1)return dp[now][bs.to_ulong()];

	bool ok = false;
	if(bs.count()==vs.size())ok=true;
	else {
		for (int i = 0; i < vs.size(); ++i) {
			if (bs[i]) {

			}
			else {
				if (vs[i].first == now || now == 7) {
					bs[i] = true;
					bool aok = solve(bs, dp, vs, vs[i].second);
					if (aok)ok = true;
					bs[i] = false;
				}
				if (vs[i].second == now || now == 7) {
					bs[i] = true;
					bool aok = solve(bs, dp, vs, vs[i].first);
					if(aok)ok=true;
					bs[i] = false;
				}
			}
		}
	
	}
	return dp[now][bs.to_ulong()]=ok;
}

void solve(vector<int>&memo,const int rest,const vector<int>&values, const vector<vector<int>>&rev_edges, int sum, int now,const vector<int>&perms,int&ans) {
	if (rest <= 0) {
		ans=min(ans,sum);
		return ;
	}
	else if (now == values.size()) {
		return;
	}
	else {
		solve(memo,rest,values,rev_edges,sum,now+1,perms,ans);

		bool ok=true;
		for (auto re : rev_edges[perms[now]]) {
			if(!memo[re])ok=false;
		}
		if (ok) {
			memo[perms[now]]=true;
			solve(memo,rest-values[perms[now]],values,rev_edges,sum+1,now+1,perms,ans);
			memo[perms[now]]=false;
		}
	}

}
int main()
{
	while (true) {
		int N,U;cin>>N>>U;
		if(!N)break;
		vector<int>values(N);
		vector<vector<int>>edges(N);
		vector<vector<int>>rev_edges(N);
		vector<int>comes(N);
		for (int i = 0; i < N; ++i) {
			int c,k;cin>>c>>k;
			values[i]=c;
			for (int j = 0; j < k; ++j) {
				int a;cin>>a;
				edges[a].push_back(i);
				rev_edges[i].push_back(a);
				comes[i]++;
			}
		}
		
		queue<int>que;
		for (int i = 0; i < N; ++i) {
			if (comes[i] == 0) {
				que.push(i);
			}
		}
		vector<int>perms;
		while (!que.empty()) {
			int atop(que.front());
			que.pop();
			perms.push_back(atop);
			for (auto e : edges[atop]) {
				comes[e]--;
				if (comes[e] == 0) {
					que.push(e);
				}
			}
		}
		vector<int>rev_perms(N);
		for (int i = 0; i < N; ++i) {
			rev_perms[perms[i]]=i;
		}
		int ans=100;
		vector<int>memo(N);
		solve(memo,U,values,rev_edges,0,0,perms,ans);
		cout<<ans<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3140
final_rank: 1

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	int points;
	vector<int> next_SUBJECT;
};

struct Data{
	int sum_points,number,subj_num;
	short in_num[20];
};

int N,need_points,POW[21];
Info info[20];
int first_in_num[20];
bool LOG[1048576];

void copyData(Data& to,Data from){
	for(int i = 0; i < N; i++){
		to.in_num[i] = from.in_num[i];
	}
}

void func(){

	for(int i = 0; i < N; i++)info[i].next_SUBJECT.clear();
	for(int i = 0; i < POW[N]; i++)LOG[i] = false;

	int num,tmp;

	for(int i = 0; i < N; i++){
		scanf("%d %d",&info[i].points,&num);
		first_in_num[i] = num;

		for(int k = 0; k < num; k++){
			scanf("%d",&tmp);
			info[tmp].next_SUBJECT.push_back(i);
		}
	}

	queue<Data> Q;

	for(int i = 0; i < N; i++){
		if(first_in_num[i] == 0){
			Data new_data;
			for(int k = 0; k < N; k++)new_data.in_num[k] = first_in_num[k];
			new_data.subj_num = 1;
			new_data.sum_points = info[i].points;
			new_data.number = POW[i];
			LOG[POW[i]] = true;
			for(int k = 0; k < info[i].next_SUBJECT.size(); k++){
				new_data.in_num[info[i].next_SUBJECT[k]]--;
			}
			Q.push(new_data);
		}
	}

	while(!Q.empty()){

		if(Q.front().sum_points >= need_points){
			printf("%d\n",Q.front().subj_num);
			return;
		}else{

			for(int loop = 0; loop < N; loop++){
				if(Q.front().number & (1 << loop)){
					//Do nothing
				}else{
					if(Q.front().in_num[loop] == 0){
						Data new_data;
						copyData(new_data,Q.front());
						new_data.subj_num = Q.front().subj_num+1;
						new_data.sum_points = Q.front().sum_points+info[loop].points;
						new_data.number = Q.front().number+POW[loop];
						if(LOG[new_data.number])continue;
						LOG[new_data.number] = true;
						for(int k = 0; k < info[loop].next_SUBJECT.size(); k++){
							new_data.in_num[info[loop].next_SUBJECT[k]]--;
						}
						Q.push(new_data);
					}
				}
			}
			Q.pop();
		}
	}
}

int main(){

	for(int i = 0; i <= 20; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d",&N,&need_points);
		if(N == 0 && need_points == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 14740
final_rank: 18

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n, U, a[20], b[20], c, r[20], popcount[1048588], sum[1048588];
vector<pair<int, int>>popcnts[21];
int main() {
	for (int i = 0; i < 20; i++) {
		for (int j = 1 << i; j < 2 << i; j++) {
			popcount[j] = popcount[j - (1 << i)] + 1;
		}
	}
	for (int i = 1; i <= 20; i++) {
		for (int j = 0; j < (1 << i); j++)popcnts[i].push_back(make_pair(popcount[j], j));
		sort(popcnts[i].begin(), popcnts[i].end());
	}
	while (scanf("%d%d", &n, &U), n) {
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &a[i], &b[i]); r[i] = 0;
			for (int j = 0; j < b[i]; j++) {
				scanf("%d", &c);
				r[i] |= 1 << c;
			}
		}
		sum[0] = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 1 << i; j < 2 << i; j++) {
				sum[j] = sum[j - (1 << i)] + a[i];
			}
		}
		int minx = 10000000;
		for (int h = 0; h < (1 << n); h++) {
			int i = popcnts[n][h].second;
			if (sum[i] < U)continue;
			bool flag = false;
			int G = (1 << n) - i - 1;
			for (int j = 0; j < n; j++) {
				if ((i & (1 << j)) && (G & r[j])) {
					flag = true;
					break;
				}
			}
			if (!flag) { minx = min(minx, popcount[i]); break; }
		}
		cout << minx << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 27680
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
 
using namespace std;
 
#define MAX 20
#define INF 1e9
 
vector<int> vec,v[MAX],a[MAX];
 
void init(int N){
    vec.clear();
    for(int i = 0 ; i < MAX ; i++){
	v[i].clear();
    }
    for(int i = 1 ; i < 1<<N ; i++){
	int idx = __builtin_popcount(i);
	v[idx-1].push_back(i);
    }
    for(int i = 0 ; i < N ; i++){
	for(int j = 0 ; j < (int)v[i].size() ; j++){
	    vec.push_back(v[i][j]);
	}
    }
}
 
int main(){
    int N,U,c[MAX],k,r;
    bool used[MAX] = {false};
 
    while(cin >> N >> U, (N | U)){
	if(!used[N-1]){
	    init(N);
	    a[N-1] = vec;
	    used[N-1] = true;
	}else{
	    vec = a[N-1];
	}
	int arr[MAX];
	for(int i = 0 ; i < N ; i++){
	    cin >> c[i] >> k;
	    int S = 0;
	    for(int j = 0 ; j < k ; j++){
		cin >> r;
		S |= 1<<r;
	    }
	    arr[i] = S;
	}
	int ans = INF;
	for(int i = 0 ; i < (int)vec.size() ; i++){
	    int S = vec[i];
	    int cnt = 0, total = 0;
	    bool flg = true;
	    for(int j = 0 ; j < N ; j++){
		if(S >> j & 1){
		    if((S & arr[j]) == arr[j]){
			cnt += c[j]; total++;
		    }else{
			flg = false;
			break;
		    }
		}
	    }
	    if(flg && cnt >= U){
		ans = total;
		break;
	    }
	}
	cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 16428
final_rank: 12

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

inline int popcount(uint x)
{
	x=(x&0x55555555)+(x>>1&0x55555555);
	x=(x&0x33333333)+(x>>2&0x33333333);
	x=(x&0x0f0f0f0f)+(x>>4&0x0f0f0f0f);
	x=(x&0x00ff00ff)+(x>>8&0x00ff00ff);
	return (x&0x0000ffff)+(x>>16&0x0000ffff);
}

int dfs(const vvi& g,int u)
{
	int res=1<<u;
	for(int v:g[u]) res|=dfs(g,v);
	return res;
}

int main()
{
	for(int n,m;~scanf("%d%d",&n,&m) && n|m;){
		vi cs(n);
		vvi g(n);
		rep(i,n){
			scanf("%d",&cs[i]);
			int k; scanf("%d",&k);
			rep(j,k){
				int r; scanf("%d",&r);
				g[i].push_back(r);
			}
		}
		
		vi bs(n);
		rep(i,n) bs[i]=dfs(g,i);
		
		vi sums(1<<n);
		rep(i,n) sums[1<<i]=cs[i];
		rep(i,1<<n) sums[i]=sums[i&-i]+sums[i-(i&-i)];
		
		int res=INF;
		rep(i,1<<n) if(popcount(i)<res){
			int b=0;
			rep(j,n) b|=(i>>j&1)*bs[j];
			if(sums[b]>=m) res=min(res,popcount(b));
		}
		printf("%d\n",res);
	}
}
accuracy: 1
time_ms: 680
memory_kb: 5292
final_rank: 10

code_snippet: // 22:45~

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

inline int popcount(uint x)
{
	x=(x&0x55555555)+(x>>1&0x55555555);
	x=(x&0x33333333)+(x>>2&0x33333333);
	x=(x&0x0f0f0f0f)+(x>>4&0x0f0f0f0f);
	x=(x&0x00ff00ff)+(x>>8&0x00ff00ff);
	return (x&0x0000ffff)+(x>>16&0x0000ffff);
}

int dfs(const vvi& g,int u)
{
	int res=1<<u;
	for(int v:g[u]) res|=dfs(g,v);
	return res;
}

int main()
{
	//clock_t t0=clock();
	for(int n,m;~scanf("%d%d",&n,&m) && n|m;){
		array<int,20> cs;
		vvi g(n);
		rep(i,n){
			scanf("%d",&cs[i]);
			int k; scanf("%d",&k);
			rep(j,k){
				int r; scanf("%d",&r);
				g[i].push_back(r);
			}
		}
		
		array<int,20> bs;
		rep(i,n) bs[i]=dfs(g,i);
		
		static array<int,1<<20> sums; sums.fill(0);
		
		rep(i,n) sums[1<<i]=cs[i];
		rep(i,1<<n) sums[i]=sums[i&-i]+sums[i-(i&-i)];
		
		int res=INF;
		rep(i,1<<n) if(popcount(i)<res){
			int b=0;
			rep(j,n) b|=(i>>j&1)*bs[j];
			if(sums[b]>=m) res=min(res,popcount(b));
		}
		printf("%d\n",res);
	}
	//clock_t t1=clock();
	//printf("%.3f[s]\n",1.*(t1-t0)/CLOCKS_PER_SEC);
}
accuracy: 1
time_ms: 650
memory_kb: 5292
final_rank: 8

code_snippet: // 22:45~

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

int dfs(const vvi& g,int u)
{
	int res=1<<u;
	for(int v:g[u]) res|=dfs(g,v);
	return res;
}

int main()
{
	//clock_t t0=clock();
	for(int n,m;~scanf("%d%d",&n,&m) && n|m;){
		array<int,20> cs;
		vvi g(n);
		rep(i,n){
			scanf("%d",&cs[i]);
			int k; scanf("%d",&k);
			rep(j,k){
				int r; scanf("%d",&r);
				g[i].push_back(r);
			}
		}
		
		array<int,20> bs;
		rep(i,n) bs[i]=dfs(g,i);
		
		static array<int,1<<20> sums; sums.fill(0);
		
		rep(i,n) sums[1<<i]=cs[i];
		rep(i,1<<n) sums[i]=sums[i&-i]+sums[i-(i&-i)];
		
		int res=INF;
		per(i,1<<n) if(__builtin_popcount(i)<res){
			int b=0;
			rep(j,n) b|=(i>>j&1)*bs[j];
			if(sums[b]>=m) res=min(res,__builtin_popcount(b));
		}
		printf("%d\n",res);
	}
	//clock_t t1=clock();
	//printf("%.3f[s]\n",1.*(t1-t0)/CLOCKS_PER_SEC);
}
accuracy: 1
time_ms: 1000
memory_kb: 5292
final_rank: 15

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
 
static const double EPS = 1e-8;

static const int tx[] = {0,1,0,-1};
static const int ty[] = {-1,0,1,0};

int prior[21];
int credit[21];
int dp[1<<20];
int bitcount[1<<20];
int total_subjects;
int credit_requirement;

class State {
public:
  int S;
  int sum;
  State(){}
  bool operator<(const State& s) const {
    return bitcount[S] < bitcount[s.S];
  }
  bool operator>(const State& s) const {
    return bitcount[S] > bitcount[s.S];
  }
  State(int S,int sum) : S(S),sum(sum) {}
};

int bfs(){
  priority_queue<State,vector<State>,greater<State> > que;
  que.push(State(0,0));
  int next_sum;
  int next_S;
  State s;
  int rest;
  while(!que.empty()){
    s = que.top();
    que.pop();
    for(int i = 0; i < total_subjects; i++){
      if(dp[next_S = (s.S | (1<<i))] != -1) continue;
      if((prior[i] | s.S) == s.S){
	next_sum = s.sum + credit[i];
	dp[next_S] = next_sum;

	if(next_sum >= credit_requirement) {
	  return bitcount[s.S] + 1;
	}
	que.push(State(next_S,next_sum));
      }
    }
  }
  return 0;
}

int main(){
  for(int S = 0; S < (1<<20); S++){
    bitcount[S] = __builtin_popcount(S);
  }
  
  while(~scanf("%d %d",&total_subjects,&credit_requirement)){
    if(total_subjects == 0 && credit_requirement == 0) break;
    memset(dp,-1,sizeof(dp));
    memset(prior,0,sizeof(prior));

    for(int subject_i = 0; subject_i < total_subjects; subject_i++){
      int prior_subject_num;
      scanf("%d %d",&credit[subject_i],&prior_subject_num);
      for(int subject_j = 0; subject_j < prior_subject_num; subject_j++){
	int subject_code;
	scanf("%d",&subject_code);
	prior[subject_i] |= (1<<subject_code);
      }
    }
    
    printf("%d\n",bfs());
  }
}
accuracy: 1
time_ms: 890
memory_kb: 16292
final_rank: 20

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int g[21];
int t[21];
//pair<pair<int,int>,int>p[21];
//int conv[];
int bp[1<<20];
int main(){
	int a,b;
	for(int i=0;i<(1<<20);i++)bp[i]=__builtin_popcount(i);
	while(scanf("%d%d",&a,&b),a){
		for(int i=0;i<a;i++)
			g[i]=0;
		for(int i=0;i<a;i++){
			int c;scanf("%d%d",t+i,&c);
			for(int j=0;j<c;j++){
				int d;scanf("%d",&d);
				g[i]+=1<<d;
			}
		}
	//	for(int i=0;i<a;i++)p[i]=make_pair(t[i],g[i]),;
	//	std::sort(p,p+a);
	//	for(int i=0;i<a;i++){
	//		t[i]=p[a-1-i].first;
	//		g[i]=p[a-1-i].second;
	//	}
		int sum=0;
		for(int i=0;i<a;i++)sum+=t[i];
		int ret=999999999;
		for(int i=0;i<(1<<a);i++){
			int q=bp[i];
			if(ret<=q)continue;
			int s=sum;
			bool ok=true;
			for(int j=0;j<a;j++){
				if(i&(1<<j)){
					if((i&g[j])!=g[j]){ok=false;break;}
				}else{
					s-=t[j];
					if(s<b){ok=false;break;}
				}
			}
			if(ok)ret=q;
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 530
memory_kb: 5112
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
struct node{
  int bits, cost;
};
node info[20];
int n, U;
int dp[1 << 20];

int rec(int used, int sbj){ //used: 修得済みの教科
  if(~dp[used]) return dp[used];
  if(sbj >= U) return __builtin_popcount(used);
  int ret = n;
  for(int i = 0; i < n; i++){
    if(info[i].bits&~used || used >> i & 1) continue;
    ret = min( ret, rec( used|(1 << i), sbj + info[i].cost));
  }
  return dp[used] = ret;
}

int main(){
  while(cin >> n >> U, n){
    fill_n( dp, 1 << 20, -1);
    for(int i = 0; i < n; i++){
      int k;
      cin >> info[i].cost >> k;
      info[i].bits = 0;
      while(k--){
        int r;
        cin >> r;
        info[i].bits |= 1 << r;
      }
    }
    cout << rec( 0, 0) << endl;
  }
}
accuracy: 1
time_ms: 610
memory_kb: 5260
final_rank: 7

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define MAX 20
#define INF 1e9

vector<int> vec,v[MAX],a[MAX];

void init(int N){
  vec.clear();
  for(int i = 0 ; i < MAX ; i++){
    v[i].clear();
  }
  for(int i = 1 ; i < 1<<N ; i++){
    int idx = __builtin_popcount(i);
    v[idx-1].push_back(i);
  }
  for(int i = 0 ; i < N ; i++){
    for(int j = 0 ; j < (int)v[i].size() ; j++){
      vec.push_back(v[i][j]);
    }
  }
}

int main(){
  int N,U,c[MAX],k,r;
  bool used[MAX] = {false};

  while(cin >> N >> U, (N | U)){
    if(!used[N-1]){
      init(N);
      a[N-1] = vec;
      used[N-1] = true;
    }else{
      vec = a[N-1];
    }
    int arr[MAX];
    for(int i = 0 ; i < N ; i++){
      cin >> c[i] >> k;
      int S = 0;
      for(int j = 0 ; j < k ; j++){
        cin >> r;
        S |= 1<<r;
      }
      arr[i] = S;
    }
    int ans = INF;
    for(int i = 0 ; i < (int)vec.size() ; i++){
      int S = vec[i];
      int cnt = 0, total = 0;
      bool flg = true;
      for(int j = 0 ; j < N ; j++){
        if(S >> j & 1){
          if((S & arr[j]) == arr[j]){
            cnt += c[j]; total++;
          }else{
            flg = false;
            break;
          }
        }
      }
      if(flg && cnt >= U){
        ans = total;
        break;
      }
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 14580
final_rank: 13

code_snippet: #include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;


int popcount32(unsigned int x){
	x = (x>>1 & 0x55555555)+(x & 0x55555555);
	x = (x>>2 & 0x33333333)+(x & 0x33333333);
	x = (x>>4 & 0x0f0f0f0f)+(x & 0x0f0f0f0f);
	x = (x>>8 & 0x00ff00ff)+(x & 0x00ff00ff);
	return (x>>16)+(x & 0x0000ffff);
}

int main(){
	int tanni[20];
	int prelearn[20];
	int n,u;
	while(cin>>n>>u,n|u){
		memset(tanni,0,sizeof(tanni));
		memset(prelearn,0,sizeof(prelearn));
		for(int i=0;i<n;i++){
			int c,k;
			cin>>c>>k;
			tanni[i]=c;
			for(int j=0;j<k;j++){
				int r;
				cin>>r;
				prelearn[i]|=1<<r;
			}
		}
		int ans=n;
		for(int i=0;i<(1<<n);i++){
			int pop=popcount32(i);
			if(ans<=pop)continue;
			int pre=0;
			for(int j=0;j<n;j++){
				pre|=(i>>j&1)*prelearn[j];
			}
			if((i&pre)!=pre)continue;
			int s=0;
			for(int j=0;j<n;j++){
				s+=(i>>j&1)*tanni[j];
			}
			if(u<=s)ans=pop;
		}
		cout<<ans<<endl;
	}
    return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 1160
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <iterator>
#include <bitset>
#include <random>
#include <assert.h>
#include <unordered_map>
#include <array>
#include <ctime>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second
#define MP make_pair
#define umap unordered_map

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> P;
typedef unsigned int uint;

int c[20], v[20];
int visit[1 << 20];
int ans;
int n, U;

void dfs(int cnt, int bits, int sum){
	if (visit[bits]) return;
	visit[bits] = 1;
	if (ans <= cnt) return;
	if (sum >= U){
		ans = cnt;
		return;
	}

	for (int i = 0; i < n; ++i){
		if (bits&(1 << i))continue;
		if ((bits&v[i]) != v[i]) continue;
		dfs(cnt + 1, bits | (1 << i), sum + c[i]);
	}
}

int main(){
	while (cin >> n >> U, n|U){
        rep(i, n){
            cin >> c[i];
            int k;
            cin >> k;
			v[i] = 0;
            rep(j, k){
                int x;
                cin >> x;
                v[i] |= 1<<x;
            }
        }
        ans = n;
		MEMSET(visit, 0);
		dfs(0, 0, 0);
        cout << ans << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 5264
final_rank: 2

code_snippet: #include<cstdio>
#include<iostream>
#include<bitset>
#include<deque>
#include<algorithm>
using namespace std;

struct Pox
{
  int state,cost;
  Pox(int state,int cost):state(state),cost(cost){}
};

int main()
{
  while(1)
    {
      int n,U,k,r;
      scanf("%d %d",&n,&U);
      if(n+U == 0)
	break;
      int mincost[1<<n];
      for(int i=0;i<(1<<n);i++)
	mincost[i] = (1<<n);
      deque<Pox> deq;
      int G[n];
      int c[n];
      for(int i = 0;i<n;i++)
	{
	  scanf("%d %d",&c[i],&k);
	    G[i] = 0;

	  for(int j=0;j<k;j++)
	    {
	      scanf("%d",&r);
	      G[i] |= (1<<r);
	    }
	}

      deq.push_back(Pox(0,0));
      mincost[0] = 0;     
      int ans = (1<<n);
      while(!deq.empty())
	{
	  Pox pox = deq.front(); deq.pop_front();
	  int num = __builtin_popcount(pox.state);
	  if(num >= ans)
	    continue;
   
	  if(pox.cost >= U)
	    {
	      ans = min(ans,num);
	      continue;
	    }	 

	  for(int i=0;i<n;i++)
	    {
	      if((pox.state >> i) & 1)
		continue;
	      int pre = G[i];
	      pre &= pox.state;
	      if(pre != G[i])
		continue;
	      if(mincost[pox.state|(1<<i)] <= num+1)
		continue;
	      mincost[pox.state|(1<<i)] = num+1;
	      if(pox.cost + c[i] < U)
		deq.push_back(Pox(pox.state|(1<<i),pox.cost+c[i]));
	      else 
		ans = min(ans,num+1);
	    }
	}
      cout << ans << endl;
    }
  return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 6928
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <map>

using namespace std;

typedef pair<int, int> P;

const int N = 20;

int n, U, C[N], K[N], R[N];
bool vis[1<<N];

int solve(){
  queue<P> q;
  q.push(P(0, 0));
  fill(vis, vis+(1<<n), false);
  while(!q.empty()){
    P u = q.front(); q.pop();
    if(u.second >= U){
      int res = 0;
      for(int i=0;i<n;i++) if((u.first >> i) & 1) res++;
      return res;
    }
    if(vis[u.first]) continue;
    vis[u.first] = true;
    for(int i=0;i<n;i++){
      if(!((u.first >> i) & 1) && (u.first & R[i]) == R[i]){
        q.push(P(u.first | (1<<i), u.second + C[i]));
      }
    }
  }
}

main(){
  while(scanf("%d %d", &n, &U) && (n|U)){
    for(int i=0;i<n;i++){
      scanf("%d %d", &C[i], &K[i]);
      R[i] = 0;
      for(int j=0;j<K[i];j++){
        int r;
        scanf("%d", &r);
        R[i] |= 1 << r;
      }
    }
    printf("%d\n", solve());
  }
}
accuracy: 1
time_ms: 650
memory_kb: 18476
final_rank: 17

code_snippet: #include<iostream>
#include<queue>
using namespace std;

struct Data{
  int used;
  int credit;
};

int n,U,c,k,r;
int credit[20],required[20];

int bitcount(int n){return n?(n&1)+bitcount(n>>1):0;}
int BFS(){
  bool visited[1<<20]={0};
  queue<Data>q;
  Data now={0,0};
  q.push(now);
  while(!q.empty()){
    now=q.front();
    q.pop();
    if(visited[now.used])continue;
    visited[now.used]=true;
    if(now.credit>=U)return bitcount(now.used);
    for(int i=0;i<n;i++){
      if(now.used & (1<<i) || (now.used & required[i]) != required[i])continue;
      Data next=now;
      next.used^=(1<<i);
      next.credit+=credit[i];
      q.push(next);
    }
  }
  return -1;
}

int main()
{
  while(cin>>n>>U,n|U){
    for(int i=0;i<n;i++){
      cin>>c>>k;
      credit[i]=c;
      required[i]=0;
      for(int j=0;j<k;j++){
        cin>>r;
        required[i]^=(1<<r);
      }
    }
    cout<<BFS()<<endl;
  }
}
accuracy: 1
time_ms: 610
memory_kb: 18500
final_rank: 16

code_snippet: #include <iostream>
#include <cstring>
using namespace std;

#define MAX_N 20

int n, U;
int cs[MAX_N];
int rs[MAX_N];

inline bool check(int S) {
    // 履修に必要な単位をすべて取得しているか
    for (int i = 0; i < n; i++) {
        if (S & (1<<i)) {
            if ((S & rs[i]) != rs[i]) {
                return false;
            }
        }
    }

    // 総単位数がUを越えているか
    int unit = 0;
    for (int i = 0; i < n; i++) {
        if (S & (1<<i)) {
            unit += cs[i];
        }
    }
    if (unit < U) return false;

    return true;
}

bool checkAllPattern(int k) {
    int c = (1<<k)-1;
    while (c < (1<<n)) {
        if (check(c)) return true;
        int x = c & -c;
        int y = c + x;
        c = ((c & ~y) / x >> 1) | y;
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    while (cin >> n >> U, n || U) {
        memset(cs, 0, sizeof(cs));
        memset(rs, 0, sizeof(rs));
        for (int i = 0; i < n; i++) {
            int c, k, r;
            cin >> c >> k; r = 0;
            for (int j = 0; j < k; j++) {
                int _r; cin >> _r;
                r |= (1<<_r);
            }
            cs[i] = c;
            rs[i] = r;
        }

        for (int i = 1; i <= n; i++) {
            if (checkAllPattern(i)) {
                cout << i << endl;
                break;
            }
        }

        //int ans = (1<<28);
        //for (int S = 1; S < (1<<n); S++) {
        //    if (check(S)) {
        //        ans = min(ans, __builtin_popcount(S));
        //    }
        //}

        //cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 830
memory_kb: 1196
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct Tag {
    int pat, value, cost;
    Tag(int p, int v, int c) : pat(p), value(v), cost(c) {}
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while(true) {
        int N, U;
        cin >> N >> U;
        if(!N && !U) break;

        vector<int> need_mask(N, 0);
        vector<int> value(N, 0);
        for(int i = 0; i < N; ++i) {
            int K;
            cin >> value[i] >> K;
            int mask = 0;
            while(K--) {
                int R;
                cin >> R;
                mask |= (1<<R);
            }
            need_mask[i] = mask;
        }
        int ans = N;
        vector<int> seen(1<<N, 0);
        queue<Tag> q;
        q.push(Tag(0, 0, 0));
        seen[0] = 1;
        while(!q.empty()) {
            Tag t = q.front();
            if(t.value >= U) {
                ans = t.cost;
                break;
            }
            q.pop();
            for(int i = 0; i < N; ++i) {
                if(!(t.pat & (1<<i)) && (t.pat & need_mask[i]) == need_mask[i]) {
                    int next_pat = t.pat | (1<<i);
                    if(!seen[next_pat]) {
                        seen[next_pat] = 1;
                        q.push(Tag(next_pat, t.value + value[i], t.cost + 1));
                    }
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 7672
final_rank: 4