• 20191111luogu1273有线电视网


    luogu1273有线电视网

    题意:
    n-m+1~n的点都为用户,用户与用户的点之间没有父子关系,其余的点不是用户,用户有权值
    点与点间需要消耗边权值才能搭建这一条边,从根节点需要经过边才能到达用户并获得点权值
    求在不亏损的情况下,能达到的用户最大为多少?

    树形背包dp:
    f[u][j]表示以u为根节点到达j个用户的最大利润(利润可能为负,代表亏损)
    考虑转移:
    对于用户来说f[u][1]=点权值
    对非用户点来说,初始时f[u][0]=0(f[u][1]以及其他都为-inf,因为他本身不是用户点)
    j的最大值为它的子树包含的用户点的数目(注意不是点的数目而是用户点的数目)
    f[u][j] = max(f[u][j],f[u][j - k] + f[too][k] - val[i]);
    最后求使f[1][j]大于等于0的最大的j值即可
    时间复杂度:O(nm^2)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 int to[6005],head[6005],nxt[6005],cnt,val[6005];
     6 int a[3005],siz[3005],f[3005][3005];
     7 int n,m;
     8 void add(int u,int v,int w)
     9 {
    10     to[++cnt] = v;
    11     nxt[cnt] = head[u];
    12     head[u] = cnt;
    13     val[cnt] = w;
    14 }
    15 void dfs(int u,int fa)
    16 {
    17     f[u][0] = 0;
    18     if(u >= n - m + 1)
    19     {
    20         f[u][1] = a[u];
    21         siz[u] = 1;
    22     }
    23     for(int i = head[u];i;i=nxt[i])
    24     {
    25         int too = to[i];
    26         if(too == fa)continue;
    27         dfs(too,u);
    28         siz[u] += siz[too];
    29         for(int j = siz[u];j >= 1;j --)
    30         {
    31             for(int k = 1;k <= min(j,siz[too]);k ++)
    32             {
    33                 f[u][j] = max(f[u][j],f[u][j - k] + f[too][k] - val[i]);
    34                 
    35 //            printf("f[%d][%d]==%d + f[%d][%d]==%d - %d = %d
    ",u,j - k,f[u][j-k],too,k,f[too][k],val[i],f[u][j]);
    36             }
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     scanf("%d%d",&n,&m);
    43     for(int i = 1,k;i <= n - m;i ++)
    44     {
    45         scanf("%d",&k);
    46         for(int j = 1,v,w;j <= k;j ++)
    47         {
    48             scanf("%d%d",&v,&w);
    49             add(i,v,w);
    50         }
    51     }
    52     for(int i = n - m + 1;i <= n;i ++)
    53     {
    54         scanf("%d",&a[i]);
    55     }
    56     memset(f,-0x3f,sizeof(f));
    57     dfs(1,0);
    58     for(int i = m;i >= 0;i --)
    59     {
    60 //        printf("f[1][%d]=%d
    ",i,f[1][i]);
    61         if(f[1][i] >= 0)
    62         {
    63             printf("%d",i);
    64             break;
    65         }
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    React简介
    webpack处理项目中的资源文件
    ajax
    DOW
    webpack-css单独打包配置
    SSH配置
    html-webpack
    常用ui
    git命令备忘
    关于git的一些使用
  • 原文地址:https://www.cnblogs.com/djfuuxjz/p/11833571.html
Copyright © 2020-2023  润新知