解题:POI 2009 Fire Extinguishers

题面

洛谷数据非常水,建议去bzoj

我第一眼一看这不是那个POI2011的升级版吗(明明这个是2009年的,应该说那个是这个的弱化版,果然思想差不多。

因为$k$很小,可以考虑每个间隔距离来转移。我们按照传统(雾,其实这里的的名字已经不是很符合定义了,设$cov[i][j]$表示以$i$为根的子树里剩余控制距离为$j$的点还能控制几个点,$unc[i][j]$表示以$i$为根的子树里还没被覆盖的距离等于$j$的点有几个。每次从儿子获取信息后先更新$cov[x][k]$,然后就是这“类”题的关键:$cov$和$unc$这两个数组如何互相抵消。

考虑贪心,对于除了根节点以外的点,我们只让它的$cov[i][j]$去和$unc[i][j-1]$和$unc[i][j]$抵消,也就是只和过了这个点就抵消不了的抵消。可能你会问为什么要抵消距离为$j-1$的点(看起来它们是可以交给父亲抵消的),这是因为我们再往上走一步会导致控制距离减一,实际距离加一,这样一来其实是抵消不了的。

注意在根节点还要把剩下的没抵消掉的抵消.......

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=100005,K=22;
 6 int p[N],noww[2*N],goal[2*N];
 7 long long cov[N][K],unc[N][K];
 8 long long s,k,cst,ans;
 9 int n,t1,t2,cnt;
10 void link(int f,int t)
11 {
12     noww[++cnt]=p[f];
13     goal[cnt]=t,p[f]=cnt;
14 }
15 void DFS(int nde,int fth)
16 {
17     unc[nde][0]=1;
18     for(int i=p[nde];i;i=noww[i])
19         if(goal[i]!=fth)
20         {
21             DFS(goal[i],nde);
22             for(int j=1;j<=k;j++)
23             {
24                 unc[nde][j]+=unc[goal[i]][j-1];
25                 cov[nde][k-j]+=cov[goal[i]][k-j+1];
26             }
27         }
28     long long tmp=(unc[nde][k]+s-1)/s; 
29     ans+=tmp,cov[nde][k]+=tmp*s;
30     for(int i=0;i<=k;i++)
31         if(cov[nde][i])
32         {
33             for(int j=i;~j;j--)
34                 if(i-j<=1||nde==1)
35                 {
36                     if(cov[nde][i]<=unc[nde][j])
37                     {
38                         unc[nde][j]-=cov[nde][i];
39                         cov[nde][i]=0; break;
40                     }
41                     cov[nde][i]-=unc[nde][j],unc[nde][j]=0;
42                 }
43                 else break;
44         }
45 }
46 int main ()
47 {
48     scanf("%d%lld%lld",&n,&s,&k);
49     for(int i=1;i<n;i++)
50     {
51         scanf("%d%d",&t1,&t2);
52         link(t1,t2),link(t2,t1);
53     }
54     DFS(1,0);
55     for(int i=0;i<=k;i++) 
56         cst+=unc[1][i]; 
57     printf("%lld",ans+(cst+s-1)/s);
58     return 0;
59 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/9769992.html