• BZOJ2427:[HAOI2010]软件安装(树形DP,强连通分量)


    Description

    现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

    但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。

    我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

    Input

    第1行:N, M  (0<=N<=100, 0<=M<=500)
    第2行:W1, W2, ... Wi, ..., Wn (0<=Wi<=M )
    第3行:V1, V2, ..., Vi, ..., Vn  (0<=Vi<=1000 )
    第4行:D1, D2, ..., Di, ..., Dn(0<=Di<=N, Di≠i )

    Output

    一个整数,代表最大价值。

    Sample Input

    3 10
    5 5 6
    2 3 4
    0 1 1

    Sample Output

    5

    Solution 

    首先按依赖关系建个图……然后tarjan缩个点……缩完后会是若干棵树的形态……
    将若干棵树连向一个根然后DP……设f[x][i]表示在x点装了空间i的最大价值……

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (1000000+1000)
     5 using namespace std;
     6 
     7 struct Edge{int to,next;}edge[N];
     8 int Dfn[N],Low[N],Col[N],stack[N],Ind[N],top,dfs_num,col_num;
     9 int n,m,w[N],v[N],d[N],W[N],V[N],head[N],f[105][505],num_edge;
    10 bool vis[N];
    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 Tarjan(int x)
    20 {
    21     Dfn[x]=Low[x]=++dfs_num;
    22     stack[++top]=x; vis[x]=true;
    23     for (int i=head[x]; i; i=edge[i].next)
    24         if (!Dfn[edge[i].to])
    25             Tarjan(edge[i].to),Low[x]=min(Low[x],Low[edge[i].to]);
    26         else if (vis[edge[i].to])
    27             Low[x]=min(Low[x],Dfn[edge[i].to]);
    28     if (Dfn[x]==Low[x])
    29     {
    30         vis[x]=false; Col[x]=++col_num;
    31         W[col_num]=w[x]; V[col_num]=v[x];
    32         while (stack[top]!=x)
    33         {
    34             vis[stack[top]]=false;
    35             Col[stack[top]]=col_num;
    36             W[col_num]+=w[stack[top]];
    37             V[col_num]+=v[stack[top--]];
    38         }
    39         --top;
    40     }
    41 }
    42 
    43 void DP(int x)
    44 {
    45     for(int i=head[x]; i; i=edge[i].next)
    46     {
    47         DP(edge[i].to);
    48         for(int j=m-W[x]; j>=0; --j)
    49             for(int k=0; k<=j; ++k)
    50                 f[x][j]=max(f[x][j],f[x][k]+f[edge[i].to][j-k]);        
    51     }
    52     for(int j=m;j>=0;j--)
    53     {
    54         if(j>=W[x]) f[x][j]=f[x][j-W[x]]+V[x];
    55         else f[x][j]=0;
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     scanf("%d%d",&n,&m);
    62     for (int i=1; i<=n; ++i) scanf("%d",&w[i]);
    63     for (int i=1; i<=n; ++i) scanf("%d",&v[i]);
    64     for (int i=1; i<=n; ++i) 
    65     {
    66         scanf("%d",&d[i]);
    67         if (d[i]) add(d[i],i);
    68     }
    69     for (int i=1; i<=n; ++i)
    70         if (!Dfn[i]) Tarjan(i);
    71     
    72     memset(head,0,sizeof(head)); num_edge=0;
    73     for (int i=1; i<=n; ++i)
    74         if (d[i] && Col[i]!=Col[d[i]])
    75             add(Col[d[i]],Col[i]),Ind[Col[i]]++;
    76     for (int i=1; i<=col_num; ++i)
    77         if (!Ind[i]) add(col_num+1,i);
    78     DP(col_num+1);
    79     printf("%d
    ",f[col_num+1][m]);
    80 }
  • 相关阅读:
    MVC框架简介
    模型-视图-控制器模式
    高德地图基本开发
    质量属性的六个常见属性场景分析
    架构漫谈读后感
    第十周
    第九周总结
    第八周总结
    springboot基于mybatis的pegehelper分页插件
    webmagic之爬取数据存储为TXT
  • 原文地址:https://www.cnblogs.com/refun/p/9609598.html
Copyright © 2020-2023  润新知