
小 A 和他的大家庭外出度假,他们想要乘着彩虹欣赏周围的景色,但是这样最会有一些问题。
在他们家族中,如果一个人想要骑上彩虹,那么他喜欢的所有人和喜欢他的所有人都必须一同骑上彩虹。如果一个人没有喜欢的人,也没有人喜欢他,那么他也可以乘上彩虹。
你被请来解决这个难题,小 A 会提供给你家族所有成员的体重,以及每个人喜欢的人的列表,同样给出的还有彩虹能承受的总重量,你需要计算出在以上条件下彩虹所能承载的最多人数。
为了方便描述,所有的家庭成员都被标号,从 1 到 n。
从 rainbow.in 读入数据。
有多组数据,每组数据之间有一空行。
对于每一组数据,第一行两个整数 n,c,其中 n 表示家庭成员的总人数,c 表示彩虹的承载量。
第二行为 n 个数为 1 到 n 个家庭成员的体重 ai。
接下来 n 行,每行第一个数 ki 表示第 i 个人有多少喜欢的人,接下来 ki 个整数为他喜欢的人的编号。
当 n=0 且 c=0 时则表示数据结束。
输出到 rainbow.out 中。
对于每一组数据,输出可以同时骑彩虹的最大人数。
5 200
50 50 50 50 50
1 2
1 3
0
1 5
1 4
3 200
100 100 100
1 2
1 3
1 1
0 0
3
0
对于 20% 的数据,1≤n≤8;
对于 100% 的数据,1≤n,c,ai≤1000,保证数据组数不超过 3。
#include<iostream>
#include<string.h>
using namespace std;
int dp[1005],fa[1005],a[1005];
int gen(int x){
	return ((fa[x]==x)?x:fa[x]=gen(fa[x]));
}
int main(){
	freopen("rainbow.in","r",stdin);
	freopen("rainbow.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	int n,c;
	while(cin>>n>>c){
		if(n==0&&c==0)break;
		for(int i=1;i<=n;i++){
			fa[i]=i;
		}
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++){
			int x;
			cin>>x;
			for(int j=1;j<=x;j++){
				int y;
				cin>>y;
				int gi=gen(i),gy=gen(y);
				if(gi!=gy){
					fa[gi]=gy;
					a[gy]+=a[gi];
				}
			}
		}
		memset(dp,0,sizeof dp);
		for(int i=1;i<=n;i++){
			if(fa[i]==i){
				for(int j=c;j>=a[i];j--){
					dp[j]=max(dp[j],dp[j-a[i]]+1);
				}
			}
		}
		cout<<dp[c]<<'\n';
	}
	return 0;
}