cogs 444. [HAOI2010]软件安装
★★☆ 输入文件:install.in
输出文件:install.out
简单对比
时间限制:1 s 内存限制:128 MB
【问题描述】
现在我们的手头有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
题解:
根据依赖关系可以画出来一张图,有三种可能的情况:1.依赖关系构成一棵树 2.依赖关系构成一个环 3.依赖关系构成一个环下面吊着一棵树。因为有2,3这些情况,所以要先有tarjan预处理一下,缩环为点,重新建图。
对于建好的图,跑一边树形背包即可,思想类似于01背包,f[x][tot]表示以x为根,容量为tot的最大收益。把x的各个子树看成物品,再枚举每个子树所分给的容量,tot从大到小转移。
还有一点,f[x][tot]保证x要算进去,最后处理一下即可保证。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=,maxm=;
int N,M,W[maxn],V[maxn],fa[maxn];
int val[maxn],cost[maxn],f[maxn][maxm]; vector<int> to[maxn],son[maxn];
int stac[maxn],top=,dfn[maxn],low[maxn],inkin[maxn],tot,Index;
bool instac[maxn];
vector<int> kin[maxn];
inline void tarjan(int x){
dfn[x]=low[x]=Index++;
stac[++top]=x;
instac[x]=true;
for(int i=;i<to[x].size();i++){
int y=to[x][i];
if(dfn[y]==-){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(instac[y]!=){
low[x]=min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]){
tot++;
int y;
do{
y=stac[top--];
instac[y]=false;
kin[tot].push_back(y);
inkin[y]=tot;
}while(y!=x);
}
}
inline void calc(int x){
if(son[x].size()==){
for(int i=cost[x];i<=M;i++) f[x][i]=val[x];
return ;
}
for(int i=;i<son[x].size();i++) calc(son[x][i]); for(int i=;i<son[x].size();i++){
int y=son[x][i];
for(int tot=M;tot>=;tot--){
for(int j=;j<=tot;j++){
f[x][tot]=max(f[x][tot],f[x][tot-j]+f[y][j]);
}
}
}
for(int i=M;i>=;i--){
if(i>=cost[x]) f[x][i]=f[x][i-cost[x]]+val[x];
else f[x][i]=;
}
}
int main(){
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=;i<=N;i++){
scanf("%d",&fa[i]);
to[fa[i]].push_back(i);
}
memset(dfn,-,sizeof(dfn));
for(int i=;i<=N;i++){
if(dfn[i]==-) tarjan(i);
}
for(int i=;i<=tot;i++){
int y=kin[i][];
if(kin[i].size()>=){//形成一个环 ,取其中任意一点,缩环为点
val[y]=V[y]; cost[y]=W[y];
son[].push_back(y);
for(int j=;j<kin[i].size();j++){
val[y]+=V[kin[i][j]];
cost[y]+=W[kin[i][j]];
}
}
else{//是一棵树上的某一点,直接复制
if(fa[y]==)
son[].push_back(y);
else{
int xx=inkin[fa[y]];
int yy=kin[xx][];
son[yy].push_back(y);
}
val[y]=V[y]; cost[y]=W[y];
}
}
val[]=; cost[]=; calc();
printf("%d",f[][M]);
return ;
}
cogs 444. [HAOI2010]软件安装的更多相关文章
- BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP
BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP 题意: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁 ...
- 【BZOJ2427】[HAOI2010]软件安装(动态规划,Tarjan)
[BZOJ2427][HAOI2010]软件安装(动态规划,Tarjan) 题面 BZOJ 洛谷 题解 看到这类题目就应该要意识到依赖关系显然是可以成环的. 注意到这样一个性质,依赖关系最多只有一个, ...
- 洛谷 P2515 [HAOI2010]软件安装 解题报告
P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...
- [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1987 Solved: 791[Submit][Statu ...
- bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp
[HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2029 Solved: 811[Submit][Status][Dis ...
- Tarjan+树形DP【洛谷P2515】[HAOI2010]软件安装
[洛谷P2515][HAOI2010]软件安装 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得 ...
- 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
[BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...
- bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1053 Solved: 424[Submit][Statu ...
- HAOI2010软件安装(树形背包)
HAOI2010软件安装(树形背包) 题意 有n个物品,每个物品最多会依赖一个物品,但一个物品可以依赖于一个不独立(依赖于其它物品)的物品,且可能有多个物品依赖一个物品,并且依赖关系可能形成一个环.现 ...
随机推荐
- linux中使用arcpy
切换到对应目录 即下图的 server安装路径 /home/arcgis/arcgis/server/tools 然后输入 ./python (这一步要注意 python这个命令 ...
- 学习计划 nginx 中 php的配置详解
本章只看一个刚下载的nginx是如何支持php的 -- location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_inde ...
- LeetCode 第 338 题 (Counting Bits)
Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the ...
- html+css小总结
html+css小总结 1.块级元素 <div> <h1> <hr /> <p> <pre> <ol> <ul> & ...
- 第一课 JDK环境变量配置
第一步:下载,并解压到D:/JDK 第二步:环境变量配置 右键我的电脑->属性->高级->环境变量->系统变量(注意:是下面的系统变量,不是上面的用户变量) 新建变量名 JAV ...
- Jquery WeUI(一)
用于微信端的控件UI , 首先,需要做的是开发一个微信能访问的网页,并和微信关联 A. 创建一个空网站 B. 增加一般处理程序 A. 增加 web 网页 和空文件到项目中 B. 申请和配置测试服务 创 ...
- Rufus 制作 USB 启动盘简单教程
制作 Windows 10 启动盘 U盘 / USB 安装盘图文教程 http://rufus.akeo.ie/downloads/rufus-2.2p.exe 1.将U盘连接到电脑,以管理员身份运 ...
- vue学习之六路由系统
一.vueRouter实现原理 VueRouter的实现原理是根据监控锚点值的改变,从而不断修改组件内容来实现的,我们来试试不使用VueRouter,自己实现路由控制,如下代码: <!DOCTY ...
- 图结构练习——判断给定图是否存在合法拓扑序列(sdutoj)
#include<stdio.h>#include<string.h>int d[15],map[15][15],vis[15];int main(){ int i,j, ...
- 【转】SVM入门(一)SVM的八股简介
(一)SVM的八股简介 支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本.非线性及高维模式识别中表现出许多特有的优势,并能够 ...