对于每一个删点操作,我们考虑当前节点的樱花数量。
由于我们要尽可能地多删点,所以我们要尽量删除樱花数少的点。
对于每一个节点,我们将它的儿子节点按照樱花数量从小到大排序,优先选择樱花数量更小的那个节点,判断是否符合条件,如果是,则删除。
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define ll long long
#define rel(i,x,y) for(ll i=(x);i<(y);i++)
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
#define res(i,x) for(ll i=head[x];i;i=nxt[i])
using namespace std;
const ll N=2e6+5;
const ll Inf=1e18;
const db Eps=1e-10;
ll n,m,tot,c[N];
vector<ll>ed[N];
inline ll read() {
ll x=0;char ch=getchar();bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
bool cmp(ll p,ll q) {
return c[p]<c[q];
}
void dfs(ll x) {
rel(i,0,ed[x].size()) dfs(ed[x][i]);
sort(ed[x].begin(),ed[x].end(),cmp);
c[x]+=ed[x].size();
rel(i,0,ed[x].size()) {
ll ret=c[ed[x][i]];
if(c[x]+ret-1<=m) {
tot++;c[x]+=ret-1;
} else break;
}
}
int main() {
n=read(),m=read();
rep(i,1,n) c[i]=read();
rep(i,1,n) {
ll cnt=read();
while(cnt--) {
ll j=read()+1;
ed[i].push_back(j);
}
}
dfs(1);
printf("%lld\n",tot);
return 0;
}