zoukankan      html  css  js  c++  java
  • BZOJ5072:[Lydsy1710月赛]小A的树(树形DP)

    Description

    BZOJ只是扔了个下载链接

    Solution

    设$f[x][i]$表示$x$点选中$i$个黑点的最小连通块。

    设$g[x][i]$表示$x$点选中$i$个黑点的最大连通块。

    转移非常明显。处理出每个情况的上下界之后差分一下$O(1)$回答询问即可。

    卡空间所以要用$short$。 第二次$INF$开大了……应该多上点心了……

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (5009) 
     5 using namespace std;
     6 
     7 struct Edge{int to,next;}edge[N<<1];
     8 int n,u,v,T,q,INF=1e4,size[N],b[N];
     9 short f[N][N],g[N][N],tmpf[N],tmpg[N],ans[N][N];
    10 int head[N],num_edge;
    11 
    12 void add(int u,int v)
    13 {
    14     edge[++num_edge].to=v;
    15     edge[num_edge].next=head[u];
    16     head[u]=num_edge;
    17 }
    18 
    19 void Dfs(int x,int fa)
    20 {
    21     size[x]=1;
    22     for (int i=0; i<=n; ++i)
    23         f[x][i]=INF,g[x][i]=-INF;
    24     f[x][b[x]]=g[x][b[x]]=1;
    25     for (int i=head[x]; i; i=edge[i].next)
    26         if (edge[i].to!=fa)
    27         {
    28             int to=edge[i].to;
    29             Dfs(to,x);
    30             for (int j=0; j<=size[x]+size[to]; ++j)
    31                 tmpf[j]=INF,tmpg[j]=-INF;
    32             for (int j=0; j<=size[x]; ++j)
    33                 for (int k=0; k<=size[to]; ++k)
    34                 {
    35                     tmpf[j+k]=min((int)tmpf[j+k],(int)f[x][j]+f[to][k]);
    36                     tmpg[j+k]=max((int)tmpg[j+k],(int)g[x][j]+g[to][k]);
    37                 }
    38             size[x]+=size[to];
    39             for (int j=0; j<=size[x]; ++j)
    40             {
    41                 f[x][j]=min(f[x][j],tmpf[j]);
    42                 g[x][j]=max(g[x][j],tmpg[j]);
    43             }
    44         }
    45     for (int i=0; i<=size[x]; ++i)
    46         if (f[x][i]<INF)
    47             ans[f[x][i]][i]++,ans[g[x][i]+1][i]--;
    48 }
    49 
    50 int main()
    51 {
    52     scanf("%d",&T);
    53     while (T--)
    54     {
    55         memset(ans,0,sizeof(ans));
    56         memset(head,0,sizeof(head));
    57         num_edge=0;
    58         scanf("%d%d",&n,&q);
    59         for (int i=1; i<=n-1; ++i)
    60             scanf("%d%d",&u,&v),add(u,v),add(v,u);
    61         for (int i=1; i<=n; ++i)
    62             scanf("%d",&b[i]);
    63         Dfs(1,0);
    64         for (int i=1; i<=n; ++i)
    65             for (int j=0; j<=n; ++j)
    66                 ans[i][j]+=ans[i-1][j];
    67         for (int i=1; i<=q; ++i)
    68         {
    69             scanf("%d%d",&u,&v);
    70             if (ans[u][v]) puts("YES");
    71             else puts("NO");
    72         }
    73         puts("");
    74     }
    75 }
  • 相关阅读:
    Redis源码剖析(十一)AOF持久化
    Redis源码剖析(一)内存管理zmalloc
    Redis源码剖析(七)压缩列表
    PHP基础课程学习总结
    php标记,变量,常量
    内容控件
    WPF 面板
    OpenSSL SSL_read: Connection was reset, errno 10054
    Java Web 项目学习(三) 发布帖子 AJAX
    控件类(ControlAndFont)
  • 原文地址:https://www.cnblogs.com/refun/p/9775176.html
Copyright © 2011-2022 走看看