bzoj2427: [HAOI2010]软件安装
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
5 5 6
2 3 4
0 1 1
Sample Output
HINT
Source
- #include<cstdio>
- #include<iostream>
- #include<cmath>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- char ch;
- bool ok;
- void read(int &x){
- ok=;
- for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
- for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
- if (ok) x=-x;
- }
- const int maxn=;
- const int maxm=;
- const int inf=;
- int n,m,a[maxn],b[maxn],x,ans;
- int f[maxn][maxm],g[maxm];
- int idx,dfn[maxn],low[maxn],stack[maxn],top,cnt,bel[maxn],siz[maxn],val[maxn],deg[maxn];
- bool in[maxn],bo[maxn];
- struct Graph{
- int tot,now[maxn],son[maxn],pre[maxn];
- void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
- void dfs(int u){
- dfn[u]=low[u]=++idx,stack[++top]=u,in[u]=;
- for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
- if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
- else if (in[v]) low[u]=min(low[u],dfn[v]);
- if (dfn[u]==low[u]){
- int v; ++cnt;
- do{v=stack[top--],bel[v]=cnt,siz[cnt]+=a[v],val[cnt]+=b[v],in[v]=;}while (u!=v);
- }
- }
- /*void dp(int u){
- bo[u]=1;
- memset(f[u],195,sizeof(f[u]));
- f[u][siz[u]]=val[u];
- for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (!bo[v]){
- dp(v);
- memcpy(g,f[u],sizeof(g));
- for (int i=0;i<=m;i++) for (int j=m;j>=i;j--) g[j]=max(g[j],f[v][i]+f[u][j-i]);
- memcpy(f[u],g,sizeof(g));
- }
- f[u][0]=max(f[u][0],0);
- }*/
- /*void dp(int u,int m){
- //cout<<u<<' '<<m<<endl;
- bo[u]=1;
- for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (!bo[v]){
- for (int i=0;i<=m;i++) f[v][i]=f[u][i];
- dp(v,m-siz[v]);
- for (int i=siz[v];i<=m;i++) f[u][i]=max(f[u][i],f[v][i-siz[v]]+val[v]);
- }
- }*/
- void dp(int u,int low){
- bo[u]=;
- for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (!bo[v]){
- for (int i=low;i<=m-siz[v];i++) f[v][i+siz[v]]=f[u][i]+val[v];
- dp(v,low+siz[v]);
- for (int i=low+siz[v];i<=m;i++) f[u][i]=max(f[u][i],f[v][i]);
- }
- }
- }G1,G2;
- int main(){
- read(n),read(m);
- for (int i=;i<=n;i++) read(a[i]);
- for (int i=;i<=n;i++) read(b[i]);
- for (int i=;i<=n;i++) read(x),G1.put(x,i);
- for (int i=;i<=n;i++) if (!dfn[i]) G1.dfs(i);
- for (int u=;u<=n;u++) for (int p=G1.now[u],v=G1.son[p];p;p=G1.pre[p],v=G1.son[p])
- if (bel[u]!=bel[v]) G2.put(bel[u],bel[v]),deg[bel[v]]++;
- for (int u=;u<=n;u++) if (!deg[bel[u]]) G2.put(bel[],bel[u]);
- //G2.dp(bel[0]);
- //G2.dp(bel[0],m);
- G2.dp(bel[],);
- for (int i=;i<=m;i++) ans=max(ans,f[bel[]][i]);
- printf("%d\n",ans);
- return ;
- }
bzoj2427: [HAOI2010]软件安装的更多相关文章
- [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1987 Solved: 791[Submit][Statu ...
- bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1053 Solved: 424[Submit][Statu ...
- BZOJ2427:[HAOI2010]软件安装(树形DP,强连通分量)
Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...
- 题解【bzoj2427 [HAOI2010]软件安装】
Description 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到一台磁盘容量为\(M\)计算 ...
- [bzoj2427][HAOI2010]软件安装——强连通分量+树形DP
题目大意 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- [BZOJ2427]:[HAOI2010]软件安装(塔尖+DP)
题目传送门 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用${W}_{i}$的磁盘空间,它的价值为${V}_{i}$.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件 ...
- [BZOJ2427][HAOI2010]软件安装-tarjan缩点-树上dp
<题面> 这个题真伤人 之前Tarjan和树规都没学好,吃了不少亏,仔仔细细的搞了一天,收获颇丰 先来一个Tarjan的链接:$\mathbb{O}$ 题目的数据比较友好: $dp$不对: ...
- BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包
分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...
- [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)
如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...
随机推荐
- 动作之CCActionInstant(立即动作)家族
立即动作就是不需要时间,马上就完成的动作.立即动作的共同基类是CCActionInstant.CCActionInstant的常用子类有: CCCallFunc:回调函数包装器 CCFlipX:X轴翻 ...
- Ubuntu远程桌面xrdp方法
xrdp方式,该方法支持多用户登录并远程桌面. 首先在Ubuntu上安装GNOME界面,在终端输入命令: sudo apt-get install gnome-panel 安装完成后注销用户. 点击自 ...
- Android(java)学习笔记157:使用Dexdump等工具进行反编译
使用Dex等工具进行反编译步骤: (1)首先找到Android软件安装包中的class.dex,把APK文件改名为".zip",然后解压缩其中的class.dex文件,这是Java ...
- 转:FORM:客制化Form的菜单栏和右鍵菜單
Oracle EBS还允许客制化Form的菜单栏. 用户最多可以定义45个form-level的trigger,名称必须为SPECIALn, 其中SPECIAL1 to SPECIAL15属于Tool ...
- Ubuntu14.04服务器安装ftp
随笔记录一下Ubuntu下安装ftp 1.远程连接登录服务器之后,输入sudo apt-get update 并回车.如果不运行该命令,直接安装vsftpd,可能会出现有一些软件包无法下载. 2.输入 ...
- c#面向对象编程基础
1. 为什么要有面向对象? (1) 增加代码重用. (2)降低维护负担,将具备独特性质的代码封装起来,修改程序时,相互不会影响. 2.数据封装用来解决全局变量不易维护的问题. 3.多态: ...
- nyoj89 汉诺塔(二)
题目网址 :http://acm.nyist.net/JudgeOnline/problem.php?pid=89 汉诺塔问题的经典结论: 把i个盘子从一个柱子整体移到另一个柱子最少需要步数是 2的i ...
- jquery - ul li click 无响应
搞了很久, 发现对应jquery来说, 动态产生的ul li(其实不只是这个, 还有 table td等), 直接使用 $("#ul_div>li").click(funct ...
- 使用instsrv.exe+srvany.exe将应用程序安装为windows服务[转]
转自:http://qingmu.blog.51cto.com/4571483/1248649 一.什么是instsrv.exe和srvany.exe instsrv.exe.exe和srvany ...
- Solr使用初探——SolrJ的使用
二.SolrJ的使用 SolrJ覆盖了solr的全部功能,下面将自己在实际开发中所使用的程序粘贴出来并适当加以解释,由于本人比较菜,代码书写不是那么的精练,还请见谅. 1. 创建solrserver ...