[POI2009]GAS-Fire Extinguishers救火站
树形+背包
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long #define dec(i,l,r) for(int i=l;i>=r;--i) const int maxn=100005; ll n,s,d,hd[maxn],f[maxn][25],g[maxn][25]; struct edge{ int to,nt; }e[maxn<<1]; int tot; inline void add(int x,int y) { e[++tot].to=y;e[tot].nt=hd[x];hd[x]=tot; e[++tot].to=x;e[tot].nt=hd[y];hd[y]=tot; } ll ans; inline void dfs(int x,int fa) { for(int i=hd[x];i;i=e[i].nt){ int v=e[i].to; if(v==fa)continue; dfs(v,x); inc(k,1,d){ f[x][k]=min(f[x][k]+f[v][k-1],n); g[x][k]+=g[v][k-1]; } } g[x][0]++; if(g[x][d]){ int t=(g[x][d]-1)/s+1; f[x][0]+=min(n,s*t); ans+=t; } inc(i,0,d){ int j=d-i; ll now=min(f[x][i],g[x][j]); f[x][i]-=now;g[x][j]-=now; } inc(i,0,d-1){ int j=d-i-1; ll now=min(f[x][i],g[x][j]); f[x][i]-=now;g[x][j]-=now; } } int main() { // freopen("in.txt","r",stdin); int x,y; rd(n),rd(s),rd(d); inc(i,2,n) { rd(x),rd(y); add(x,y); } dfs(1,0); int sum=0; inc(i,0,d) dec(j,d,0) if(i+j<=d) { int now=min(f[1][i],g[1][j]); f[1][i]-=now,g[1][j]-=now; } inc(i,0,d)sum+=g[1][i]; ans+=(sum?(sum-1)/s+1:0); printf("%d",ans); re 0; }