题目描述

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

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

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

输入格式

第1行:N,M(0≤N≤100,0≤M≤500)

第2行:W_1,W_2, ... W_i, ..., W_n

第3行:V_1, V_2, ..., V_i, ..., V_n

第4行:D_1, D_2, ..., D_i, ..., D_n

输出格式

一个整数,代表最大价值


先把图缩点,变成树

然后做树上背包

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int N=505,M=10*N;
int nxt[M],head[N],go[M],tot;
inline void add(int u,int v){
nxt[++tot]=head[u];head[u]=tot;go[tot]=v;
}
int cost[N],val[N],d[N],f[N][N];
int dfn[N],low[N],co[N],st[N],col,num,top;
int c[N],va[N];
inline void Tarjan(int u){
dfn[u]=low[u]=++num;
st[++top]=u;
for(int e=head[u];e;e=nxt[e]){
int v=go[e];
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!co[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
co[u]=++col;
while(st[top]!=u){
co[st[top]]=col;
--top;
}
--top;
}
}
int in[N];
int n,m;
inline void dfs(int u){
for(int i=c[u];i<=m;i++)f[u][i]=va[u];
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
dfs(v);
for(int j=m-c[u];j>=0;j--)
for(int q=0;q<=j;q++)
f[u][j+c[u]]=max(f[u][j+c[u]],f[u][j+c[u]-q]+f[v][q]);
}
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%lld",&cost[i]);
for(int i=1;i<=n;i++)scanf("%lld",&val[i]);
for(int i=1;i<=n;i++){
scanf("%lld",&d[i]);
if(d[i])add(d[i],i);
}
for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i);
memset(nxt,0,sizeof(nxt)),memset(head,0,sizeof(head)),memset(go,0,sizeof(go)),tot=0;
for(int i=1;i<=n;i++){
c[co[i]]+=cost[i];
va[co[i]]+=val[i];
if(d[i]!=0&&co[i]!=co[d[i]])
add(co[d[i]],co[i]),in[co[i]]++;
}
int s=col+1;
for(int i=1;i<=col;i++)if(!in[i])add(s,i);
c[s]=0,va[s]=0; dfs(s);
cout<<f[s][m]<<endl;
return 0;
}

luogu P2515 [HAOI2010]软件安装 |Tarjan+树上背包的更多相关文章

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

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

  2. 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包

    [BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...

  3. 【bzoj2427】[HAOI2010]软件安装 Tarjan+树形背包dp

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

  4. BZOJ 2427: [HAOI2010]软件安装 tarjan + 树形背包

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

  5. BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包

    分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...

  6. luogu P2515 [HAOI2010]软件安装

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

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

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

  8. [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1987  Solved: 791[Submit][Statu ...

  9. HAOI2010软件安装(树形背包)

    HAOI2010软件安装(树形背包) 题意 有n个物品,每个物品最多会依赖一个物品,但一个物品可以依赖于一个不独立(依赖于其它物品)的物品,且可能有多个物品依赖一个物品,并且依赖关系可能形成一个环.现 ...

随机推荐

  1. 最新开源跳板机(堡垒机)系统 Jumpserver介绍

    Jumpserver 是全球首款完全开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 的专业运维审计系统. Jumpserver 使用 Python / Django 进行开发,遵 ...

  2. maven配置nexus私有仓库

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  3. Python字典 你必须知道的用法系列

    本文Python版本为3.7.X,阅读本文之前需了解python字典的基本用法. 介绍 字典(dict)是Python中内置的一个数据结构,由多个键值对组成,键(key)和值(value)用冒号分隔, ...

  4. python快速获取网页标准表格内容

    from html_table_parser import HTMLTableParser def tableParse(value): p = HTMLTableParser() p.feed(va ...

  5. Matlab 文件格式化/Matlab Source File Formator

    由于需要使用到别人编写的Matlab代码文件,但是呢不同的人有不同的风格,有的写得就比较糟糕了. 为了更好地理解代码的内容,一个比较美观的代码会让人身心愉悦. 但是在网上并没有找到一个比较好的实现,此 ...

  6. [ISE调试] 在ISE调试过程中,遇到过的error以及消除办法

    1.Incompatible IOB's are locked to the same bank 15,具体如右图, 于是去查引脚配置,发现 也就是说,在bank=15的这组IO里面,我既选了LVAM ...

  7. hdu 1874 畅通工程续 (dijkstra(不能用于负环))

    畅通工程续Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. 【Java】final修饰符的使用

    final修饰符的使用 1.修饰类: final修饰的类不能被继承,final修饰的类里面的方法都是(隐式)final方法 2.修饰方法: final修饰的方法不能被重写 3.修饰变量(被修饰的变量一 ...

  9. 领扣(LeetCode)最长和谐子序列 个人题解

    和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1. 现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5,2,3,7] ...

  10. 领扣(LeetCode)错误的集合 个人题解

    集合 S 包含从1到 n 的整数.不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复. 给定一个数组 nums 代表了集合 S ...