题目描述

现在我们的手头有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缩点+树形dp

屠龙宝刀点击就送

#include <ctype.h>
#include <cstdio>
#define N 605 void read(int &x)
{
x=;bool f=;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
x=f?(~x)+:x;
}
struct node
{
int next,to;
}edge[N<<];
struct node2
{
int next,to;
}edge2[N<<];
struct thing
{
int v,w;
}th[N];
bool in[N],instack[N];
int head2[N],cnt2,f[N][N],w[N],v[N],stack[N],top,n,m,head[N],cnt,sumcol,col[N],dfn[N],low[N],tim;
void add(int u,int v)
{
edge[++cnt].next=head[u];
edge[cnt].to=v;
head[u]=cnt;
}
int min(int a,int b){return a>b?b:a;}
int max(int a,int b){return a>b?a:b;}
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
instack[x]=;
stack[++top]=x;
for(int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if(instack[v]) low[x]=min(low[x],dfn[v]);
if(!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]);
}
if(low[x]==dfn[x])
{
int t;
sumcol++;
do
{
t=stack[top--];
instack[t]=false;
col[t]=sumcol;
th[sumcol].v+=v[t];
th[sumcol].w+=w[t];
}while(t!=x);
}
}
void dp(int x)//此处DP为树上01背包 
{
for(int i=head2[x];i;i=edge2[i].next)
{
dp(edge2[i].to);//延伸的点继续dp
for(int j=m-th[x].w;j>=;j--)
{
for(int k=;k<=j;k++) f[x][j]=max(f[x][j],f[x][k]+f[edge2[i].to][j-k]);
}
}
for(int j=m;j>=;j--)
{
if(j>=th[x].w) f[x][j]=f[x][j-th[x].w]+th[x].v;
else f[x][j]=;
}
}
void add2(int u,int v)
{
edge2[++cnt2].next=head2[u];
edge2[cnt2].to=v;
head2[u]=cnt2;
}
void rebuild()
{
for(int i=;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].next)
{
int v=edge[j].to;
if(col[v]!=col[i])
{
in[col[v]]=;
add2(col[i],col[v]);
}
}
}
}
int main()
{
read(n);read(m);
for(int i=;i<=n;i++) read(w[i]);
for(int i=;i<=n;i++) read(v[i]);
for(int x,i=;i<=n;i++)
{
read(x);
if(x) add(x,i);
}
for(int i=;i<=n;i++) if(!dfn[i]) tarjan(i);
rebuild();
for(int i=;i<=sumcol;i++)
{
if(!in[i])
{
in[i]=;
add2(sumcol+,i);
}
}
dp(sumcol+);
printf("%d",f[sumcol+][m]);
return ;
}

洛谷 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. 自定义custom Tab Bar

    iOS提供的Tab Bar比较简单,我们常常有些别样的需求,此时往往需要自行自定义Tab Bar,如下图所示:                           如图所示,需要在某个页面中添加一个类 ...

  2. 「网络流24题」「LuoguP4014」 分配问题

    Description 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为 cij.试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大. Input 文 ...

  3. 【旧文章搬运】Idle进程相关的一些东西

    原文发表于百度空间,2009-05-13========================================================================== Idle进 ...

  4. 【旧文章搬运】Windows内核常见数据结构(进程相关)

    原文发表于百度空间,2008-7-24========================================================================== 进程的相关结 ...

  5. 【208】CentOS 下安装 Wine

    参考:centos6.5安装wine 参考:用FreeGate自-由-门软件在Linux上更新Android SDK 参考:CentOS 5.3 使用wine装QQ

  6. Hadoop 三大调度器源码分析及编写自己的调度器

    如要转载,请注上作者和出处.  由于能力有限,如有错误,请大家指正. 须知: 我们下载的是hadoop-2.7.3-src 源码. 这个版本默认调度器是Capacity调度器. 在2.0.2-alph ...

  7. POJ 2392【多重背包】

    题意: k个块,给出每个块的高度hi,数量ci,不能超过的高度: 求这些块可以组成的最大高度一个. 思路: 大致可看这个题是一个背包,背包的承重是高度. 对于每个物品,有他的价值是高度,还有限定的数量 ...

  8. java webRoot 路径问题

    项目部署后的目录结构 src 生成到 WEB-INF\classes文件下; WebRoot  为项目的根目录,应用中“/action”就相当于是系统目录中的”WebRoot/action" ...

  9. Qt 2D绘图之一:基本图形绘制和渐变填充

    Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter.QPaintDevice和QPaintEngine这三个类.它们三者的关系如下图所示: QP ...

  10. 517 Super Washing Machines 超级洗衣机

    详见:https://leetcode.com/problems/super-washing-machines/description/ C++: class Solution { public: i ...