题目描述

  小$w$心里的火焰就要被熄灭了。
  简便起见,假设小$w$的内心是一棵$n-1$条边,$n$个节点的树。
  现在你要在每个节点里放一些个灭火器,每个节点可以放任意多个。
  接下来每个节点都要被分配给一个至多$k$条边远的灭火器,每个灭火器最多能分配给$s$个节点。
  至少要多少个灭火器才能让小$w$彻底死心呢?


输入格式

  第一行三个整数$n,s,k$。
  接下来$n-1$行每行两个整数表示一条边。


输出格式

  一行一个整数表示答案


样例

样例输入:

10 10 3
1 8
2 3
1 5
2 4
1 2
8 9
8 10
5 6
5 7

样例输出:

1


数据范围与提示

  对于$20\%$的数据满足$n\leqslant 100,k\leqslant 2$。
  对于另外$20\%$的数据满足$k=1$。
  对于另外$20\%$的数据满足$s=1$。
  对于$100\%$的数据满足$n\leqslant 10^5,k\leqslant 20,s\leqslant 10^9$。


题解

先来考虑贪心,依次选还没有被覆盖的深度最大的点一定更优,这个用一个堆维护就好啦。

但是可能存在灭火器交集很大的情况。

再来考虑$DP$,设$G[x][k]$表示$x$下面距离为$k$的需要灭火器的房间数,$F[x][k]$表示$x$下面距离为$k$的多余灭火器数。

首先$G[x][k]$要与$F[x][0]$匹配。

还要注意可以跨国$LCA$,所以$G[x][i]$也可以与$F[x][k-i]$匹配,$G[x][i]$与$F[x][k-i-1]$匹配。

那么有转移:

$$F[u][i]=\sum\limits_vF[v][i-1]$$

$$G[u][i]=\sum\limits_vG[v][i+1]$$

初始化$F[x][i]=G[x][i]=1$即可。

匹配的时候用指针维护就好了。

时间复杂度:$\Theta(nk)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to;}e[200000];
int head[100001],cnt;
int n,s,k;
int f[100001][21],g[100001][21];
bool vis[100001];
int ans,sum;
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs(int x)
{
vis[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
if(vis[e[i].to])continue;
dfs(e[i].to);
for(int j=1;j<=k;j++)
{
f[x][j]+=f[e[i].to][j-1];
g[x][j-1]+=g[e[i].to][j];
g[x][j-1]=min(g[x][j-1],n);
}
}
f[x][0]++;
if(f[x][k])
{
int tmp=(ceil)((double)f[x][k]/s);
ans+=tmp;
g[x][k]+=min(tmp*s,n)-f[x][k];
f[x][k]=0;
}
int fail=k;
for(int i=k;~i;i--)
while(f[x][i]&&fail>=i)
{
int flag=min(f[x][i],g[x][fail]);
f[x][i]-=flag;g[x][fail]-=flag;
if(!g[x][fail])fail--;
}
}
int main()
{
scanf("%d%d%d",&n,&s,&k);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1);
for(int i=0;i<=k;i++)sum+=f[1][i];
ans+=(ceil)((double)sum/s);
printf("%d",ans);
return 0;
}

rp++

最新文章

  1. webstorm license key
  2. JQ 常见demo
  3. [转载]C#使用Interlocked进行原子操作
  4. 演示一个OLS进行数据访问控制的示例
  5. Codeforces Round #382 (Div. 2) A. Ostap and Grasshopper bfs
  6. CSS笔记(十三)CSS3之过渡
  7. linux安装 Android Studio详细教程,支持性较差,需要安装最新底层库内核的linux
  8. Sicily-1134
  9. ionic+AnjularJs实现省市县三级联动效果
  10. Erlang 编写 Kafka 客户端之最简单入门
  11. matplotlib坐标轴刻度-【老鱼学matplotlib】
  12. [hdu3466]Proud Merchants
  13. 解压安装的tomcat, 使用chkconfig命令让tomcat 随机启动,tomcat 变为系统服务
  14. HttpClient配置SSL绕过https证书
  15. oracle表结构和数据导出时的一些勾选项说明
  16. jquery 分页 下拉框
  17. RPC框架之Thrift分析(转)
  18. Vue 传递
  19. JS的Scope
  20. [PHP]如何使用Mobile_Detect来判断访问网站的设备:安卓,平板,电脑

热门文章

  1. ModbusRtu通信报文详解【二】
  2. 微信小程序上传图片及本地测试
  3. Fox新闻报道,帮助北朝鲜使用加密货币专家被捕
  4. CSS3--transform相关属性
  5. C# 移除数组中重复项
  6. 记录一则ORA
  7. VIM技巧----改变
  8. 查看ocx控件CLSID的方法(转载)
  9. windows10家庭版远程桌面连接报错:CredSSP加密oracle修正
  10. Bind+DLZ构建企业智能DNS/DNS