Title Description
Small $ w $ in the heart of the flame will be extinguished.
Simplicity, let's say $ W $ heart is a $ n-1 $ edges, n-$ $ tree nodes.
Now you want to put some fire extinguishers at each node, each node can put any number.
Next, each node must be assigned to a strip of at most $ k $ remote fire extinguisher, a fire extinguisher for each assigned to up to $ s $ nodes.
At least the number of fire extinguishers to make small $ w $ completely give up hope it?
Input Format
The first row of three integers $ n, s, k $.
Next, $ n-1 $ lines each represent an integer of two sides.
Output Format
Integer answer a row
Sample
Sample input:
10 10 3
1 8
2 3
1 5
2 4
1 2
8 9
8 10
5 6
5 7
Sample output:
1
Data range and tips
For $ 20 \% $ data satisfies $ n \ leqslant 100, k \ leqslant 2 $.
For another $ 20 \% $ data satisfies $ k = 1 $.
For another $ 20 \% $ data satisfies $ s = 1 $.
Data for $ 100 \% $ satisfies $ n \ leqslant 10 ^ 5, k \ leqslant 20, s \ leqslant 10 ^ 9 $.
answer
Consider first greedy, in turn elect the deepest point it has not covered some better, with a heap maintain this Jiuhaola.
But there may be a fire extinguisher intersection great situation.
Consider again $ DP $, set $ G [x] [k] $ denotes $ X $ following distance is the number of $ k $ need extinguisher room, $ F [x] [k] $ denotes $ X $ following distance is $ the excess number of fire extinguishers k $.
First $ G [x] [k] $ to [x] [0] $ matches $ F.
Note also be cross $ LCA $, so $ G [x] [i] $ may also be $ F [x] [ki] $ match, $ G [x] [i] $ and $ F [x] [ki -1] $ match.
Then there is the transfer:
$$F[u][i]=\sum\limits_vF[v][i-1]$$
$$G[u][i]=\sum\limits_vG[v][i+1]$$
Initialization $ F [x] [i] = G [x] [i] = 1 $ can.
When matched with the pointer maintain enough.
Time complexity: $ \ Theta (nk) $.
Expectations score: $ 100 $ points.
Actual score: $ 100 $ points.
Code time
#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++