[HAOI2010]软件安装

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2029  Solved: 811
[Submit][Status][Discuss]

Description

现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。

我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

Input

第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 )

Output

一个整数,代表最大价值。

Sample Input

3 10
5 5 6
2 3 4
0 1 1

Sample Output

5

HINT

 
树形,dp依赖型的,算完点,是一棵树对吧,然后就从根向下dp数据范围如此之小。
f[i][j]表示i这个点,可以用安装连续几个点的方案数。
 
 #include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio> #define N 107
#define M 507
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,cnt,scc,ind,top;
int v[N],w[N];
int sv[N],sw[N];
int dfn[N],low[N],belong[N];
int q[N],f[N][M],in[M];
struct edge{
int to,next;
}e[M],ed[M];int last[N],last2[N];
bool inq[N]; void insert(int u,int v){e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;}
void insert2(int u,int v)
{
in[v]=;
ed[++cnt].to=v;ed[cnt].next=last2[u];last2[u]=cnt;
}
void tarjan(int x)
{
int now=;
low[x]=dfn[x]=++ind;
q[++top]=x;inq[x]=;
for(int i=last[x];i;i=e[i].next)
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if(inq[e[i].to])
low[x]=min(low[x],dfn[e[i].to]);
if(low[x]==dfn[x])
{
scc++;
while(now!=x)
{
now=q[top--];inq[now]=;
belong[now]=scc;
sv[scc]+=v[now];
sw[scc]+=w[now];
}
}
}
void rebuild()
{
cnt=;
for(int x=;x<=n;x++)
for(int i=last[x];i;i=e[i].next)
if(belong[e[i].to]!=belong[x])
insert2(belong[x],belong[e[i].to]);
}
void dp(int x)
{
for(int i=last2[x];i;i=ed[i].next)
{
dp(ed[i].to);
for(int j=m-sw[x];j>=;j--)
{
for(int k=;k<=j;k++)
f[x][j]=max(f[x][j],f[x][k]+f[ed[i].to][j-k]);
}
}
for(int j=m;j>=;j--)
{
if(j>=sw[x])f[x][j]=f[x][j-sw[x]]+sv[x];
else f[x][j]=;
}
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++) w[i]=read();
for(int i=;i<=n;i++) v[i]=read();
for(int i=;i<=n;i++)
{
int x=read();
if(x)insert(x,i);
}
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i);
rebuild();
for(int i=;i<=scc;i++)
if(!in[i])
insert2(scc+,i);
dp(scc+);
printf("%d\n",f[scc+][m]);
}
 

bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp的更多相关文章

  1. BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP

    终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...

  2. BZOJ 2427: [HAOI2010]软件安装 tarjan + 树形背包

    Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...

  3. 【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)

    点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...

  4. [BZOJ2427][HAOI2010]软件安装-tarjan缩点-树上dp

    <题面> 这个题真伤人 之前Tarjan和树规都没学好,吃了不少亏,仔仔细细的搞了一天,收获颇丰 先来一个Tarjan的链接:$\mathbb{O}$ 题目的数据比较友好: $dp$不对: ...

  5. bzoj 2427: [HAOI2010]软件安装【tarjan+树形dp】

    一眼最大权闭合子图,然后开始构图,画了画之后发现我其实是个智障网络流满足不了m,于是发现正确的打开方式应该是一眼树上dp 然后仔细看了看性质,发现把依赖关系建成图之后是个奇环森林,这个显然不能直接dp ...

  6. bzoj 2427: [HAOI2010]软件安装

    Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...

  7. BZOJ 2427 [HAOI2010]软件安装 | 这道树形背包裸题严谨地证明了我的菜

    传送门 BZOJ 2427 题解 Tarjan把环缩成点,然后跑树形背包即可. 我用的树形背包是DFS序上搞的那种. 要注意dp数组初始化成-INF! 要注意dp顺推的时候也不要忘记看数组是否越界! ...

  8. BZOJ 2427: [HAOI2010]软件安装( dp )

    软件构成了一些树和一些环, 对于环我们要不不选, 要么选整个环. 跑tarjan缩点后, 新建个root, 往每个入度为0的点(强连通分量) 连边, 然后跑树dp( 01背包 ) ---------- ...

  9. 【洛谷 P2515】 [HAOI2010]软件安装 (缩点+树形背包)

    题目链接 看到代价和价值这两个关键词,肯定是首先要想到背包的. 但是图中并没有说这是棵树,所以先要\(Tarjan\)缩点,然后就是选课了,跑一遍树形背包就好了. 注意:缩点后应该是一个森林,应该用一 ...

随机推荐

  1. Kubernetes-apiserver

    Kubernetes API服务器为API对象验证和配置数据,这些对象包含Pod.Service.ReplicationController等等.API Server提供REST操作以及前端到集群的共 ...

  2. POJ 3210 : Coins

    参考:https://blog.csdn.net/u010885899/article/details/46636523 http://kqwd.blog.163.com/blog/static/41 ...

  3. 一步一步学Linq to sql(六):探究特性

    延迟执行 IQueryable query = from c in ctx.Customers select c; 这样的查询句法不会导致语句立即执行,它仅仅是一个描述,对应一个SQL.仅仅在需要使用 ...

  4. 1754-I Hate It 线段树(单点替换,区间最值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  5. express操作数据库

    Express 首页 入门 使用指南 API 中文手册 进阶话题 有用的资源 集成数据库 为 Express 应用添加连接数据库的能力,只需要加载相应数据库的 Node.js 驱动即可.这里将会简要介 ...

  6. html5学得好不好,看掌握多少标签

    html5学得好不好,看掌握多少标签 已回复 会员ID:wi701329 保密 62岁 时间:2016-06-28 06:52:49 html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的 ...

  7. Android中StackOverflow的问题

    最近出现了一个让人抓狂的问题. 现在的项目中,制作了一个界面非常复杂.Fragment中嵌套下拉刷新的Listview 这样一个布局,在3.0以上的手机上都表现良好问题!但是在2.x的比较弱爆的手机上 ...

  8. CSS3 : box-shadow

    box-shadow 用于设置边框阴影,语法: box-shadow: h-shadow v-shadow blur spread color inset; -moz-box-shadow: h-sh ...

  9. 09-Mysql数据库----外键的变种

    本节重点: 如何找出两张表之间的关系 表的三种关系 一.介绍 因为有foreign key的约束,使得两张表形成了三种了关系: 多对一 多对多 一对一 二.重点理解如果找出两张表之间的关系 分析步骤: ...

  10. 初识Django —Python API接口编程入门

    初识Django —Python API接口编程入门 一.WEB架构的简单介绍 Django是什么? Django是一个开放源代码的Web应用框架,由Python写成.我们的目标是用Python语言, ...