BZOJ 4027 HEOI2015 rabbit and sakura tree greedy
Given a tree with roots, each node has some cherry blossoms. Now we need to delete some nodes. The cherry blossoms and subnodes that Delete the nodes will be connected to the parent node, the number of cherry blossoms and subnodes per node must not exceed M , How many nodes can be deleted at most
This data range can only be greedy =
Ling Fi Is a node I The maximum number of nodes that can be deleted in the root subtree ( I Node is not deleted ), Gi When the maximum number of nodes is deleted I Minimum Load on node No.
First, we try to delete all the child trees with the root node for each node, and then consider how to delete the child nodes.
For nodes X And X Subnode Y , If you delete Y Node Gx Contribution Gy? 1
Therefore, we X Click Gy? 1 Sort, from small to large
Why is this true?
We consider the impact of a subtree on the parent node. Only when the root of the subtree is deleted will the content on the root be inserted to the parent node.
If a subtree is not deleted most often, the only advantage is that there are fewer things inserted to the Father's Day when the root is deleted.
In this way, the final benefit is only [the root node can be deleted from being deleted]
As a result, I do not want to delete the root node, and then let the child tree Delete more? =
Therefore, greed is right.
#include
#include
#include
#include #define M 2002002using namespace std;struct abcd{ int to,next;}table[M];int head[M],tot;int n,m;int a[M],f[M],g[M];bool not_root[M];void Add(int x,int y){ table[++tot].to=y; table[tot].next=head[x]; head[x]=tot;}void Tree_Greedy(int x){ int i,top=0; for(i=head[x];i;i=table[i].next) { Tree_Greedy(table[i].to); f[x]+=f[table[i].to]; g[x]++; } static int stack[M]; g[x]+=a[x]; for(i=head[x];i;i=table[i].next) stack[++top]=g[table[i].to]-1; sort(stack+1,stack+top+1); for(i=1;i<=top;i++) if(g[x]+stack[i]<=m) f[x]++,g[x]+=stack[i]; else break;}int main(){ int i,j,k,x; cin>>n>>m; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) { scanf("%d",&k); for(j=1;j<=k;j++) { scanf("%d",&x); Add(i,++x); not_root[x]=true; } } for(i=1;i<=n;i++) if(!not_root[i]) { Tree_Greedy(i); cout<