Description
很久很久之前,森林裏住着一羣兔子。有一天,兔子們突然決定要去看櫻花。兔子們所在森林裏的櫻花樹很特殊。櫻花樹由n個樹枝分叉點組成,編號從
現在兔子們覺得櫻花樹上節點太多,希望去掉一些節點。當一個節點被去掉之後,這個節點上的櫻花和它的兒子節點都被連到刪掉節點的父節點上。如果父節點也被刪除,那麼就會繼續向上連接,直到第一個沒有被刪除的節點爲止。
現在兔子們希望計算在不違背最大載重的情況下,最多能刪除多少節點。
注意根節點不能被刪除,被刪除的節點不被計入載重。
Solution
誒竟然1A了,不可思議。
這個貪心感覺很奇怪。。
首先如果
還有一件事就是如果點
反正都是縮一個,觀察,若縮下面,就這樣,但縮上面,可能干擾其它點縮,並且下面的也不可能再縮上去,虧了,所以縮下面即可。
那麼就是一遍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;
}