傳送門
一道貪心題
首先我們可以證明最優的貢獻一定是從下依次合併到上的
不會出現乙個節點不能合併到父親節點,卻能合併到父親節點的祖先節點的情況
我們設當前的節點為 \(u\),\(u\) 的父親節點為 \(v\),\(v\) 的父親節點是 \(fa\)
如果 \(u\) 不能合併到 \(v\) 上,那麼必定有
\(c[u]+son[u]-1+c[v] +son[v]>m\)
如果我們把 \(v\) 合併到 \(fa\) 上再把 \(u\) 合併到 \(fa\) 上
那麼 \(fa\) 此時的值為
\(c[fa]+son[fa]-1+c[u]+son[u] -1+c[v]+son[v]\)
我們發現右半部分一定是大於 \(m\) 的
因此此時 \(fa\) 的值一定大於 \(m\)
所以合併的過程一定是從下到上依次進行的
不會出現將某個節點合併到父親節點後又將該節點的兒子節點合併到其父親節點上
所以我們可以一遍 \(dfs\) 求出答案
對於每乙個節點將其所有兒子節點對它的貢獻從小到大排序,依次合併,直到不能合併為止
某個節點 \(u\) 對其父親節點 \(fa\) 的貢獻為 \(son[u]+c[u]-1\)
#include#include#include#include#define rg register
const int maxn=2e6+5;
inline int read()
while(ch>='0' && ch<='9')
return x*fh;
}int h[maxn],tot=1;
struct asdb[maxn<<1];
void ad(int aa,int bb)
int son[maxn],c[maxn],n,m,ans,js[maxn];
void dfs(int now,int fa)
std::sort(g.begin(),g.end());
rg int haha=g.size()-1;
for(rg int i=0;i<=haha;i++)
} g.clear();
}int main()
for(rg int i=1;i<=n;i++)
js[i]=son[i]+c[i];
} dfs(1,0);
printf("%d\n",ans);
return 0;
}
HEOI2015 兔子和櫻花
題目傳送門 有一棵樹,裡面有很多點,每個點上有乙個櫻花量 a i a i a i 然後他的兒子數為 son i son i son i 刪除點以後這個點的櫻花和兒子都會繼承給他的父親,問最多刪除多少點,能滿足刪除的點的父親滿足 a i so n i m a i son i leq m a i s o...
HEOI2015 兔子與櫻花
一棵 n n le2 times10 6 個點的樹,每個點有乙個重量 c i 和乙個載重上限 m 刪除乙個結點時,將自身的重量加到父結點上,並將所有子結點連到父結點上。問若要保證對於任意乙個結點,子結點數與重量之和 le m 時,最多刪去幾個結點。自底向上貪心,子結點按照 c i 排序,能刪除的盡量...
bzoj4027 heoi2015 兔子與櫻花
time limit 10 sec memory limit 256 mb submit 360 solved 187 submit status discuss 很久很久之前,森林裡住著一群兔子。有一天,兔子們突然決定要去看櫻花。兔子們所在森林裡的櫻花樹很特殊。櫻花樹由n個樹枝分叉點組成,編號從0...