洛谷——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.题目中的依赖关系不一定是树,可 ...
随机推荐
- Java 学习(14):接口 & 包(设置 CLASSPATH 系统变量)
Java 接口(英文:Interface) 定义:在JAVA编程语言中,接口是一个抽象类型,是抽象方法的集合,接口通常以 interface 来声明. 一个类通过继承接口的方式,从而来继承接口的抽象方 ...
- Springboot分布式限流实践
高并发访问时,缓存.限流.降级往往是系统的利剑,在互联网蓬勃发展的时期,经常会面临因用户暴涨导致的请求不可用的情况,甚至引发连锁反映导致整个系统崩溃.这个时候常见的解决方案之一就是限流了,当请求达到一 ...
- [ES2017] Iterate over properties of an object with ES2017 Object.entries()
The Object.entries() function is an addition to the ECMAscript scpec in Es2017. This allows us to it ...
- ACM-康托展开+预处理BFS之魔板——hdu1430
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- StdTranslator - Translate PDMS to STD for STAAD.Pro
StdTranslator - Translate PDMS to STD for STAAD.Pro eryar@163.com STAAD.Pro是由美国世界著名的工程咨询和CAD软件开发公司—R ...
- python-打开网页
最近一直想通过python来实现网页的操作.因为想把自己vimrc的配置直接通过脚本来实现.比较理想的情况下,就是通过一个脚本,把自己需要的一些资源直接从网上下载下来,然后再对下载的资源进行安装等操作 ...
- SQL Server字符串分割函数
- Mysql主从级联复制
场景1 如果主节点已经运行了一段时间,且有大量数据时,如何配置并启动slave节点 通过备份恢复数据至从服务器· 复制起始位置为备份时,二进制日志文件及其POS: Mater 设置 1) 修改配置文件 ...
- Spark Tachyon的命令行使用
Tachyon命令行使用 Tachyon接口说明 接口操作示例 copyFromLocal copyToLocal ls和lsr count cat mkdir.rm.rmr和touch pin和un ...
- 洛谷P1908 逆序对(归并排序)
题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...