Description
很久很久之前,森林里住着一群兔子。有一天,兔子们突然决定要去看樱花。兔子们所在森林里的樱花树很特殊。樱花树由n个树枝分叉点组成,编号从
0
到
现在兔子们觉得樱花树上节点太多,希望去掉一些节点。当一个节点被去掉之后,这个节点上的樱花和它的儿子节点都被连到删掉节点的父节点上。如果父节点也被删除,那么就会继续向上连接,直到第一个没有被删除的节点为止。
现在兔子们希望计算在不违背最大载重的情况下,最多能删除多少节点。
注意根节点不能被删除,被删除的节点不被计入载重。
Solution
诶竟然1A了,不可思议。
这个贪心感觉很奇怪。。
首先如果
v
和它的一个子节点
还有一件事就是如果点
A
可以删
反正都是缩一个,观察,若缩下面,就这样,但缩上面,可能干扰其它点缩,并且下面的也不可能再缩上去,亏了,所以缩下面即可。
那么就是一遍dfs可以搞定的事情了。
Code
/**************************************************************
Problem: 4027
User: bblss123
Language: C++
Result: Accepted
Time:4696 ms
Memory:61080 kb
****************************************************************/
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define pb push_back
#define ph push
#define vecn vector<node>
#define pqn priority_queue<node>
#define debug cout<<#x<<" "<<x<<endl;
#define frt fisrt
#define snd second
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vec;
typedef priority_queue<int> pq;
const int INF=1<<30;
const ll inf=1ll<<60;
const int M=2e6+5;
inline void Max(int &a,int b){if(a<b)a=b;}
inline void Min(int &a,int b){if(a>b||a==-1)a=b;}
inline void rd(int &a){
a=0;char c;
while(c=getchar(),!isdigit(c));
do a=a*10+(c^48);
while(c=getchar(),isdigit(c));
}
inline void work(ll x){
if(!x)return;
work(x/10);
putchar(48+x%10);
}
inline void print(ll x){
if(!x)putchar('0');
else work(x);
}
int n,m,c[M],son[M],ans;
vec G[M];
struct node{
int val,x;
inline bool operator < (const node &tmp)const{
return val>tmp.val;
}
};
inline void dfs(int v){
pqn que;for(;!que.empty();)que.pop();
for(int i=0;i<G[v].size();++i){
int to=G[v][i];
dfs(to);
que.push((node){c[to]+son[to],to});
}
for(;!que.empty();){
node u=que.top();que.pop();
if(c[v]+son[v]+u.val-1<=m){
c[v]+=c[u.x],son[v]+=son[u.x]-1;
++ans;
}
else break;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//#define LOCAL
//////////////////////////////////////////////////////////////////////////////////////////////
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
cin>>n>>m;
for(int i=0;i<n;++i)
rd(c[i]);
for(int i=0;i<n;++i){
rd(son[i]);
for(int j=1,a;j<=son[i];++j)
rd(a),G[i].pb(a);
}
dfs(0);
cout<<ans<<endl;
return 0;
}