解题:POI 2011 Dynamite

题面

从零开始的DP学习系列之叁

树形DP的基本(常见?)思路:先递归进儿子,然后边回溯边决策,设状态时常设$dp[x]$表示以$x$为根的子树中(具体分析算不算$x$这个点)的情况

显然的二分答案,之后问题转化为用$m$个能覆盖$mid$范围的点能否覆盖所有的特殊点,用树形DP判断

设$unc[nde]$表示以$nde$为根(包含$nde$)的子树中最远的未被覆盖的特殊点的距离,$cov[nde]$以$nde$为根(包含$nde$)的子树中最近的选出的点的距离。有两个从儿子$goal[i]$获取信息的显然的转移

unc[nde]=max(unc[nde],unc[goal[i]]+1);
cov[nde]=min(cov[nde],cov[goal[i]]+1);

然后考虑对点的选择,首先如果这个点是特殊点,而且$cov[nde]>mid$,说明这个点无法被子树中的点覆盖,只能交给父亲处理,于是更新一下它的$unc$的信息,告诉它的父亲考虑这个点

if(imp[nde]&&cov[nde]>mid) unc[nde]=max(unc[nde],0);

接下来考虑这个点的子树中的特殊点(们)能否靠这个点解决,如果$unc[nde]+cov[nde]<=mid$说明这个子树不需要父亲管了

if(unc[nde]+cov[nde]<=mid) unc[nde]=-inf;

最后是考虑是否选择这个点,这里贪心考虑,只在$unc$正好等于$mid$时选择这个点

if(unc[nde]==mid) unc[nde]=-inf,cov[nde]=0,tot++;

注意的是根节点没有父亲,要特殊考虑

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=300005,inf=0x3f3f3f3f;
 6 int p[N],noww[2*N],goal[2*N];
 7 int imp[N],unc[N],cov[N];
 8 int n,m,t1,t2,cnt,tot,l,r,mid,ans;
 9 void link(int f,int t)
10 {
11     noww[++cnt]=p[f];
12     goal[cnt]=t,p[f]=cnt;
13 }
14 void DFS(int nde,int fth)
15 {
16     unc[nde]=-inf,cov[nde]=inf;
17     for(int i=p[nde];i;i=noww[i])    
18         if(goal[i]!=fth)
19         {
20             DFS(goal[i],nde);
21             unc[nde]=max(unc[nde],unc[goal[i]]+1);
22             cov[nde]=min(cov[nde],cov[goal[i]]+1);
23         }
24     if(imp[nde]&&cov[nde]>mid) unc[nde]=max(unc[nde],0);
25     if(unc[nde]+cov[nde]<=mid) unc[nde]=-inf;
26     if(unc[nde]==mid) unc[nde]=-inf,cov[nde]=0,tot++;
27 }
28 bool check(int x)
29 {
30     tot=0; DFS(1,0);
31     return tot+(unc[1]>=0)<=m;
32 }
33 int main ()
34 {
35     scanf("%d%d",&n,&m),r=n;
36     for(int i=1;i<=n;i++) 
37         scanf("%d",&imp[i]);
38     for(int i=1;i<n;i++)
39     {
40         scanf("%d%d",&t1,&t2);
41         link(t1,t2),link(t2,t1);
42     }
43     while(l<=r)
44     {
45         mid=(l+r)/2;
46         if(check(mid)) r=mid-1,ans=mid; 
47         else l=mid+1;
48     }
49     printf("%d",ans);
50     return 0;
51 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/9679292.html