码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2427 软件安装

时间:2016-02-03 19:15:29      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

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;
}

 

bzoj2427 软件安装

标签:

原文地址:http://www.cnblogs.com/ccz181078/p/5180332.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!