题目描述

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

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

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

输入输出格式

输入格式:

第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 )

输出格式:

一个整数,代表最大价值

输入输出样例

输入样例#1:

3 10
5 5 6
2 3 4
0 1 1
输出样例#1:

5

拿到这个题,我们先要对其进行tarjan缩点。为什么要tarjan缩点??因为如果图中出现了一个环这说明这些软件必须一起将这些软件一块放入,这样我们可以将这样的一个环直接看成一个软件,这个软件的价值与体积即为环内点的总价值、体积。这样的话我们直接对原图进行tarjan缩点然后再在新图上乱搞就好了、、、

我们可以发现我们缩完点后的新图是不是可能由若干个树组成,这样处理起来无疑是很麻烦的。因此我们要将这个图给连起来(怎么连??我们建一个原点,然后向缩完点后的每一棵树的树根连边),形成一棵树,然后我们在这棵树上跑树形dp就可以啦。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 1100
using namespace std;
bool vis[N],vist[N];
int n,m,y,tim,top,tot,tat,sum,ans;
int v[N],w[N],zv[N],zw[N],stack[N],low[N];
int dad[N],dfn[N],head[N],head1[N],belong[N],f[N][N];
struct Edge
{
    int to,from,next;
}edge[N],edge1[N];
int add(int x,int y)
{
    tot++;
    edge[tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
int add1(int x,int y)
{
    tat++;
    edge1[tat].to=y;
    edge1[tat].next=head1[x];
    head1[x]=tat;
}
int read()
{
    ,f=; char ch=getchar();
    ; ch=getchar();}
    +ch-'; ch=getchar();}
    return x*f;
}
int tarjan(int now)
{
    dfn[now]=low[now]=++tim;
    vis[now]=true,stack[++top]=now;
    for(int i=head[now];i;i=edge[i].next)
    {
        int t=edge[i].to;
        if(vis[t]) low[now]=min(low[now],dfn[t]);
        else if(!dfn[t]) tarjan(t),low[now]=min(low[now],low[t]);
    }
    if(dfn[now]==low[now])
    {
        sum++;belong[now]=sum;
        zw[sum]+=w[now],zv[sum]+=v[now];
        for(;stack[top]!=now;top--)
        {
            int x=stack[top];
            belong[x]=sum,vis[x]=false;
            zw[sum]+=w[x],zv[sum]+=v[x];
         }
         vis[now]=false; top--;
    }
}
int shink_point()
{
    ;i<=n;i++)
     for(int j=head[i];j;j=edge[j].next)
      if(belong[i]!=belong[edge[j].to])
      {
          dad[belong[edge[j].to]]=belong[i];
          add1(belong[i],belong[edge[j].to]);
       }
}
int dfs(int x)
{
    for(int i=head1[x];i;i=edge1[i].next)
    {
        int t=edge1[i].to;
        dfs(t);
        ;j--)
         ;k<=j;k++)
          f[x][j]=max(f[x][j],f[x][k]+f[t][j-k]);
    }
    ;i--)
     if(i>=zv[x]) f[x][i]=f[x][i-zv[x]]+zw[x];
     ;
}
int main()
{
    n=read(),m=read();
    ;i<=n;i++) v[i]=read();
    ;i<=n;i++) w[i]=read();
    ;i<=n;i++)
    {
        y=read();
        ) continue;
        add(y,i);
    }
    ;i<=n;i++)
     if(!dfn[i]) tarjan(i);
    shink_point();
    ;i<=sum;i++)
     ,i);
    dfs(sum+);
    ans=f[sum+][m];
    printf("%d",ans);
    ;
}

洛谷—— P2515 [HAOI2010]软件安装的更多相关文章

  1. 洛谷 P2515 [HAOI2010]软件安装 解题报告

    P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...

  2. 洛谷 P2515 [HAOI2010]软件安装

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

  3. 洛谷——P2515 [HAOI2010]软件安装

    https://www.luogu.org/problem/show?pid=2515#sub 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中 ...

  4. 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)

    题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...

  5. 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)

    传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...

  6. luogu P2515 [HAOI2010]软件安装 |Tarjan+树上背包

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

  7. [bzoj2427]P2515 [HAOI2010]软件安装(树上背包)

    tarjan+树上背包 题目描述 现在我们的手头有 \(N\) 个软件,对于一个软件 \(i\),它要占用 \(W_i\) 的磁盘空间,它的价值为 \(V_i\).我们希望从中选择一些软件安装到一台磁 ...

  8. P2515 [HAOI2010]软件安装

    树形背包 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> ...

  9. luogu P2515 [HAOI2010]软件安装

    传送门 看到唯一的依赖关系,容易想到树型dp,即\(f_{i,j}\)表示选点\(i\)及子树内连通的点,代价为\(j\)的最大价值,然后就是选课那道题 但是要注意 1.题目中的依赖关系不一定是树,可 ...

随机推荐

  1. java集合测试类等

    package demo.mytest; import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import ja ...

  2. LuoguP1351 联合权值 (枚举)

    题目链接 枚举每个点,遍历和他相邻的点,然后答案一边更新就可以了. 最大值的时候一定是两个最大值相乘,一边遍历一边记录就好了. 时间复杂度.\(O(n)\) #include <iostream ...

  3. vim的卸载以及环境的配置小记

    一.背景 由于之前配置错误,导致我的YouCompleteMe这个插件不能用了,一直提示: ERROR:Required vim compiled with +python. YouCompleteM ...

  4. The eleven Day

    库操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等 performance_schema ...

  5. gpio/外设/控制器

    1.项目中所有的外设pad都是通过GPIO与控制器相连的.比如FSHC<=>gpio<=>flash 2.gpio类似多个 mux 集合. 3.对于与gpio相连的pad具体结 ...

  6. Web框架之Django_08 重要组件(form组件、cookie和session组件)

    摘要: form组件 cookie组件 session组件 一.form组件 form介绍我们之前在html页面中利用form表单向后端提交数据时候,都需要对用户的输入进行校验,比如校验用户是否输入正 ...

  7. kafka异常问题汇总

    1.报错:: java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.NotLeaderForPartition ...

  8. python 购物车小程序(列表、循环、条件语句)

    goods = [ ['iphone6s', 5800], ['mac book', 9000], ['coffee', 32], ['python book', 80], ['bicyle', 15 ...

  9. foxmial 和 outlook设置问题

    您可以使用支持POP3的客户端软件(例如Foxmail或Outlook)收发您的邮件.请配置您的电子邮件客户端,以下载QQ邮箱邮件. 了解如何进行配置,请单击您的电子邮件客户端名称: Foxmail设 ...

  10. PAT Basic 1067

    1067 试密码 当你试图登录某个系统却忘了密码时,系统一般只会允许你尝试有限多次,当超出允许次数时,账号就会被锁死.本题就请你实现这个小功能. 输入格式: 输入在第一行给出一个密码(长度不超过 20 ...