洛谷——P2515 [HAOI2010]软件安装
https://www.luogu.org/problem/show?pid=2515#sub
题目描述
现在我们的手头有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 )
输出格式:
一个整数,代表最大价值
输入输出样例
3 10
5 5 6
2 3 4
0 1 1
5 f[u][i]表示安装u占用i的内存能得到的最大价值
#include <algorithm>
#include <cstdio> using namespace std; const int N();
const int M();
int n,m,w[N],v[N],f[N][M]; int hed[N],had[N],sumedge;
struct Edge
{
int v,next;
Edge(int v=,int next=):
v(v),next(next){}
}edge[M<<];
void ins(int u,int v,int *head)
{
edge[++sumedge]=Edge(v,head[u]);
head[u]=sumedge;
} int tim,dfn[N],low[N];
int Stack[N],instack[N],top;
int sumcol,col[N],cval[N],cw[N];
void DFS(int now)
{
dfn[now]=low[now]=++tim;
Stack[++top]=now; instack[now]=;
for(int i=hed[now];i;i=edge[i].next)
{
int v=edge[i].v;
if(!dfn[v]) DFS(v),low[now]=min(low[now],low[v]);
else if(instack[v]) low[now]=min(low[now],dfn[v]);
}
if(low[now]==dfn[now])
{
col[now]=++sumcol;
cw[sumcol]+=w[now];
cval[sumcol]+=v[now];
for(;now!=Stack[top];top--)
{
col[Stack[top]]=sumcol;
cw[sumcol]+=w[Stack[top]];
cval[sumcol]+=v[Stack[top]];
instack[Stack[top]]=;
}
instack[now]=;top--;
}
} int dad[N],root;
void Get_tree()
{
for(int i=;i<=n;i++)
for(int j=hed[i];j;j=edge[j].next)
{
if(col[i]==col[edge[j].v]) continue;
dad[col[edge[j].v]]=col[i];
ins(col[i],col[edge[j].v],had);
}
}
void DP(int x)
{
for(int i=had[x];i;i=edge[i].next)
{
DP(edge[i].v);
for(int j=m-cw[x];j>=;j--)
for(int k=;k<=j;k++)
f[x][j]=max(f[x][j],f[x][k]+f[edge[i].v][j-k]);
}
for(int i=m;i>=;i--)
{
if(i>=cw[x]) f[x][i]=f[x][i-cw[x]]+cval[x];
else f[x][i]=;
}
} int main()
{
// freopen("install.in","r",stdin);
// freopen("install.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",w+i);
for(int i=;i<=n;i++) scanf("%d",v+i);
for(int i=,x;i<=n;i++)
{
scanf("%d",&x);
if(x) ins(x,i,hed);
}
for(int i=;i<=n;i++)
if(!dfn[i]) DFS(i);
Get_tree();
for(int i=;i<=sumcol;i++)
if(!dad[i])
{
dad[i]=;
ins(sumcol+,i,had);
}
DP(sumcol+);
printf("%d",f[sumcol+][m]);
return ;
}
洛谷——P2515 [HAOI2010]软件安装的更多相关文章
- 洛谷 P2515 [HAOI2010]软件安装 解题报告
P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...
- 洛谷—— P2515 [HAOI2010]软件安装
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- 洛谷 P2515 [HAOI2010]软件安装
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)
题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...
- 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...
- luogu P2515 [HAOI2010]软件安装 |Tarjan+树上背包
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为MM计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但 ...
- [bzoj2427]P2515 [HAOI2010]软件安装(树上背包)
tarjan+树上背包 题目描述 现在我们的手头有 \(N\) 个软件,对于一个软件 \(i\),它要占用 \(W_i\) 的磁盘空间,它的价值为 \(V_i\).我们希望从中选择一些软件安装到一台磁 ...
- P2515 [HAOI2010]软件安装
树形背包 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> ...
- luogu P2515 [HAOI2010]软件安装
传送门 看到唯一的依赖关系,容易想到树型dp,即\(f_{i,j}\)表示选点\(i\)及子树内连通的点,代价为\(j\)的最大价值,然后就是选课那道题 但是要注意 1.题目中的依赖关系不一定是树,可 ...
随机推荐
- Add Webhooks to Your API the Right Way
Add Webhooks to Your API the Right Way Adam DuVander / December 15, 2016 In the last 10 years, APIs ...
- C++里的模板
1.泛型编程 --即实现一个通用的标准容器库. 所谓通用的标准容器库,就是要做到:比方List类存放全部肯恩类型的对象这样的事:泛型编程让你编写一个全然一般化并可反复使用的算法,其效率与针对某特定数 ...
- Android应用公布后的统计——百度移动统计的应用
一个App公布到各个渠道之后,我们须要採集不同渠道的一些信息,比方app在执行过程中产生的一些异常信息,app在各个android版本号的分布,以及各个app版本号的分布,各渠道的用户数,用户忠诚度等 ...
- 【Struts2】Struts2纯手工安装、配置以及Helloworld,以最新版struts 2.3.20 GA做样例
很多网上的教程对Struts2的配置.安装弄得不明不白,非常多高手以为小白是什么都懂.很多细节上面的地方没有说明清楚,甚至还有在Maven上面解说的,要知道Struts2跟Maven没有半点的关系.全 ...
- Linq查询案例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Kinect 开发 —— 面部追踪
SDK1.5中新增了人脸识别类库:Microsoft.Kinect.Toolkit.FaceTracking使得在Kinect中进行人脸识别变得简单,该类库的源代码也在Developer Toolki ...
- 博弈论 SG函数(模板) HDU 1848 Fibonacci again and again
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- Log4Net 用法记录
https://www.cnblogs.com/lzrabbit/archive/2012/03/23/2413180.html https://blog.csdn.net/guyswj/articl ...
- 使用Ant 和 Maven打包发布命令行程序(转载)
From:https://www.linux178.com/Java/maven-release.html 用Java写了一个命令行的小程序,使用的Intellij IDE是IDEA13原来一直使用A ...
- Directx9.0 学习教程3 -图形学之创建点 线 三角形 等
1.首先 介绍点的表示方法 struct CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, { ...