ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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

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

软件之间的关系构成树或环,暴力把环缩成一点然后就是树形背包了。

#include<cstdio>
#include<vector>
std::vector<int> ss[128];
int pa[128];
int id[128];
int w[128],v[128],fa;
int n,m;
int f[128][512];
int g[128][512];
void maxs(int&a,int b){
    if(a<b)a=b;
}
int t=0;
void dfs(int x){
    int sz=ss[x].size();
    if(sz){
        for(int i=0;i<sz;i++)dfs(ss[x][i]);
        int u=ss[x][0];
        for(int j=m;j>=0;j--)g[x][j]=f[u][j];
        for(int i=1;i<sz;i++){
            u=ss[x][i];
            for(int j=m;j>=0;j--)
            for(int k=0;k<=j;k++)
            maxs(g[x][j],g[x][j-k]+f[u][k]);
        }
        for(int j=w[x];j<=m;j++)
        f[x][j]=g[x][j-w[x]]+v[x];
    }else{
        for(int i=w[x];i<=m;i++)f[x][i]=v[x];
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",w+i);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",v+i);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&fa);
        if(i!=fa)pa[i]=fa;
        id[i]=i;
    }
    for(int i=1;i<=n;i++){
        int a=i;
        if(~pa[i])
        for(int j=1;j<=110;j++){
            a=pa[a];
            if(a<1)break;
            if(a==i){
                for(a=pa[a];a!=i&&~a;a=fa){
                    v[i]+=v[a];
                    w[i]+=w[a];
                    fa=pa[a];
                    pa[a]=-1;
                    id[a]=i;
                }
                pa[i]=0;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++){
        if(~pa[i])ss[id[pa[i]]].push_back(i);
    }
    dfs(0);
    printf("%d",f[0][m]);
    return 0;
}

 

posted on 2016-02-03 18:29  nul  阅读(258)  评论(0编辑  收藏  举报