题目描述

现在我们的手头有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. CentOS7 reset脚本,用于初始化新的虚拟机

    能用,有待完善 CentOS7测试 哈哈 #!/bin/bash #************************************************************** #Au ...

  2. 013.Kubernetes二进制部署worker节点Nginx实现高可用

    一 Nginx代理实现kube-apiserver高可用 1.1 Nginx实现高可用 基于 nginx 代理的 kube-apiserver 高可用方案. 控制节点的 kube-controller ...

  3. JDBD连接MySQL中的驱动与时区问题

    1.在进行jdbc与mysql连接的时候应注意,加载驱动的方式根据MySQL版本内容来说 有变化 5.7版本之前: String driver= "com.mysql.jdbc.Driver ...

  4. kubernetes实战(二十八):Kubernetes一键式资源管理平台Ratel安装及使用

    1. Ratel是什么? Ratel是一个Kubernetes资源平台,基于管理Kubernetes的资源开发,可以管理Kubernetes的Deployment.DaemonSet.Stateful ...

  5. C# VII: 统计文本行数

    本文基于StackOverflow的以下问题收集整理而成. What is the fastest waty to count newlines in a large .NET string: htt ...

  6. PowerMock学习之PoweMock的入门(二)

    前言 在上一篇<PowerMock学习之PoweMock的入门(一)>文章中,已经简单提及一些关于powermock的用法,但是入门还未完,我还要坚持把它学习并坚持更新到博客中. Mock ...

  7. PHP 修改数组中的值

    PHP 修改数组中的值 ①.二维数组可以通过 for($i = 0; $i < count(Array()); ++ $i) 这种形式修改 实例代码: // 修改 二维数组中的 name为 Ge ...

  8. 领扣(LeetCode)回文链表 个人题解

    请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶:你能否用 O(n) 时间复杂 ...

  9. CentOs虚拟机配置

    1.打开“VMware”,点击“主页”,点“创建新的虚拟机”: 2.会弹出一个“新建虚拟机向导”,类型选择“典型”,点击“下一步”: 3.选择“稍后安装操作系统”,点击“下一步”: 4.我们用的是Li ...

  10. vim可视化模式

    进入:v 移动光标选中 c剪切.y复制(自动退出v模式,进入插入模式) p粘贴