zoukankan      html  css  js  c++  java
  • 解题: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
  • 相关阅读:
    复制
    rpm 软件包管理
    xfsdump 备份文件系统
    dhcp服务器(一)
    【转】kafka集群搭建
    postgresql主从配置
    centos7 安装配置postgresql
    centos7 安装配置zookeeper
    zookeeper
    piplinedb 安装配置
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9769992.html
Copyright © 2011-2022 走看看