洛谷 P2515 [HAOI2010]软件安装
题目描述
现在我们的手头有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
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]软件安装的更多相关文章
- 洛谷 P2515 [HAOI2010]软件安装 解题报告
P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...
- 洛谷—— P2515 [HAOI2010]软件安装
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- 洛谷——P2515 [HAOI2010]软件安装
https://www.luogu.org/problem/show?pid=2515#sub 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为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.题目中的依赖关系不一定是树,可 ...
随机推荐
- [USACO 2016Dec] Team Building
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4742 [算法] 动态规划 用Fi,j,k表示约翰的前i头牛和保罗的前j头牛匹配 , ...
- 【前端】CentOS 7 系列教程之四: 配置 git 服务器自动部署
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_4.html 安装pm2守护进程,备用 npm install -g pm2 创建/srv/www文件夹 ...
- linux设备驱动第三篇:如何实现一个简单的字符设备驱动
在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存 ...
- eclipse导入工程报Invalid project description(转载)
转自:http://blog.sina.com.cn/s/blog_a2eab3000101k3r7.html 昨天新搭建的环境,今天把以前的项目导入eclipse时报错: 说的是我导入的项目与wor ...
- SCUT - 249 - Hello World - 数位dp
https://scut.online/p/249 数位dp的模板题? 需要特殊判断0,这个很不优雅,因为0-1=-1是个很奇葩的东西? #include<bits/stdc++.h> u ...
- PTA 模拟【string以及字母->数组下标】
假设有九宫格输入法键盘布局如下: [ 1,.?! ] [ 2ABC ] [ 3DEF ] [ 4GHI ] [ 5JKL ] [ 6MNO ] [ 7PQRS ] [ 8TUV ] [ 9WXYZ ] ...
- bzoj 5496: [2019省队联测]字符串问题【SAM+拓扑】
有一个想法就是暴力建图,把每个A向有和他相连的B前缀的A,然后拓扑一下,这样的图是n^2的: 考虑优化建图,因为大部分数据结构都是处理后缀的,所以把串反过来,题目中要求的前缀B就变成了后缀B 建立SA ...
- 报错org.springframework.dao.DataIntegrityViolationException
最简单的原因可能是数据库外键字段选择了不能为空, 改为允许为空就行了.
- 编译boost asio http/server 方法
这段时间学习boost 的asio 编程,想编译asio自带的http/server的程序,无奈在网上根本找不到方法,只能自己摸索学习. 登陆boost asio 的example 目录,(我 boo ...
- POJ 2104 K-th Number && 洛谷 P3834 【模板】可持久化线段树 1(主席树)
我惊奇的发现这两道题一模一样 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询 ...