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

输出格式:

一个整数,代表最大价值

输入输出样例

输入样例#1:

3 10

5 5 6

2 3 4

0 1 1

输出样例#1:

5

被看错题和脑抽卡了一晚上......

就是个有依赖的树形背包,但是没看到间接依赖也不能对答案造成贡献,以为像是没有上司的舞会那样的dp。

先将原图缩点,要选的话至少要选一个强连通分量,否则不能对答案造成贡献,缩完点之后就是个DAG了,直接跑树形背包就完了。(我居然连树形背包的板子都不记得了)

#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
const int N=110,M=510;
int n,m,cnt,top,visnum,num,ans;
int w[N],c[N],d[N],sumw[N],sumc[N],head[N];
int dfn[N],low[N],s[N],in[N],belong[N],du[N];
int dp[N][M];
struct node{
int to,next;
}edge[2*N];
void add(int x,int y){
cnt++;edge[cnt].to=y;edge[cnt].next=head[x];head[x]=cnt;
}
queue<int>q;
void tarjan(int k){
dfn[k]=low[k]=++visnum;
s[++top]=k;in[k]=1;
for(int i=head[k];i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);low[k]=min(low[k],low[v]);
}
else if(in[v])low[k]=min(low[k],dfn[v]);
}
if(dfn[k]==low[k]){
num++;int v=0;
while(v!=k){
v=s[top--];in[v]=0;
belong[v]=num;sumw[num]+=w[v];sumc[num]+=c[v];
}
}
}
void DP(int k){
for(int i=head[k];i;i=edge[i].next){
int v=edge[i].to;DP(v);
for(int j=m;j>=0;j--)
for(int l=j;l>=0;l--)
dp[k][j]=max(dp[k][j],dp[k][j-l]+dp[v][l]);
}
for(int i=m;i>=0;i--)
if(i>=sumw[k])
dp[k][i]=dp[k][i-sumw[k]]+sumc[k];
else dp[k][i]=0;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)w[i]=read();
for(int i=1;i<=n;i++)c[i]=read();
for(int i=1;i<=n;i++){
d[i]=read();if(d[i])add(d[i],i);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
cnt=top=0;memset(head,0,sizeof(head));
for(int i=1;i<=n;i++){
if(!d[i]||belong[i]==belong[d[i]])continue;
add(belong[d[i]],belong[i]);du[belong[i]]++;
}
for(int i=1;i<=num;i++)if(!du[i])add(0,i);
DP(0);for(int i=0;i<=m;i++)ans=max(ans,max(dp[0][i],dp[0][i]));
printf("%d",ans);return 0;
}

[HAOI2010]软件安装(Tarjan,树形dp)的更多相关文章

  1. [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)

    如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...

  2. BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP

    BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP 题意: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁 ...

  3. 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包

    [BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...

  4. 【bzoj2427】[HAOI2010]软件安装 Tarjan+树形背包dp

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

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

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

  6. BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包

    分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...

  7. bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp

    [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2029  Solved: 811[Submit][Status][Dis ...

  8. [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1987  Solved: 791[Submit][Statu ...

  9. 【BZOJ-2427】软件安装 Tarjan + 树形01背包

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 960  Solved: 380[Submit][Status ...

  10. bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1053  Solved: 424[Submit][Statu ...

随机推荐

  1. linux 下的快捷键操作

    概述 今天发现自己码代码的效率有点低,所以查找了一下 linux 常用的快捷键操作,记录下来,供以后开发时参考,相信对其他人也有用. linux 终端常用快捷键 tab:补全命令 Ctrl + u:剪 ...

  2. table 隔列换色

    $("table tr").find("td:eq(1),td:eq(2),td:eq(4)").css("background-color" ...

  3. zabbix服务端安装

    1.安装zabbix服务(1)先rpm安装lamp环境 yum install -y httpd mysql mysql-libs php php-mysql mysql-server php-bcm ...

  4. Linux下源码安装MySQL-5.6.25

    从mysql-5.5起,mysql源码安装开始使用cmake了,因此我们得先安装cmake,配置安装目录./configure --perfix=/.....的时候和以前的会有些区别. 一.安装cma ...

  5. harbor无法登陆解决

    添加如下内容 [root@bogon ~]# vi /etc/docker/daemon.json { "registry-mirrors": ["https://wb2 ...

  6. ROS自动切换策略

    自动切换策略,具体如下 监视地址:1.1.1.1 轮询时间:30s:超时时间:1000ms up /ip firewall nat set [/ip firewall nat find comment ...

  7. 病毒分析(三)-利用Process Monitor对熊猫烧香病毒进行行为分析

    前两次随笔我介绍了手动查杀病毒的步骤,然而仅通过手动查杀根本无法仔细了解病毒样本的行为,这次我们结合Process Monitor进行动态的行为分析. Process Monitor Process ...

  8. 【神经网络与深度学习】【Python开发】Caffe配置 windows下怎么安装protobuf for python

    首先从google上下载protobuf-2.5.0.zip和protoc-2.5.0-win32.zip,然后把protoc-2.5.0-win32.zip里的protoc.exe放到protobu ...

  9. 你确定 SQL 查询都是以 SELECT 开始的?

    很多 SQL 查询都是以 SELECT 开始的. 不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否可以对窗口函数返回的结果进行过滤"这个问题,得出的结论是"窗口函 ...

  10. keil格式化项目代码

    有时候需要用到一个功能,就先会在网上找到对应的程序,但是百度直接拿来的程序通常不是很规范.想着keil5要是有一个自动格式化代码的功能就好啦,上网一查还真有!需要一些设置如下(keil4与keil5都 ...