★★☆   输入文件: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要算进去,最后处理一下即可保证。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<vector>
  9. using namespace std;
  10. const int maxn=,maxm=;
  11. int N,M,W[maxn],V[maxn],fa[maxn];
  12. int val[maxn],cost[maxn],f[maxn][maxm];
  13.  
  14. vector<int> to[maxn],son[maxn];
  15. int stac[maxn],top=,dfn[maxn],low[maxn],inkin[maxn],tot,Index;
  16. bool instac[maxn];
  17. vector<int> kin[maxn];
  18. inline void tarjan(int x){
  19. dfn[x]=low[x]=Index++;
  20. stac[++top]=x;
  21. instac[x]=true;
  22. for(int i=;i<to[x].size();i++){
  23. int y=to[x][i];
  24. if(dfn[y]==-){
  25. tarjan(y);
  26. low[x]=min(low[x],low[y]);
  27. }
  28. else if(instac[y]!=){
  29. low[x]=min(low[x],dfn[y]);
  30. }
  31. }
  32. if(dfn[x]==low[x]){
  33. tot++;
  34. int y;
  35. do{
  36. y=stac[top--];
  37. instac[y]=false;
  38. kin[tot].push_back(y);
  39. inkin[y]=tot;
  40. }while(y!=x);
  41. }
  42. }
  43. inline void calc(int x){
  44. if(son[x].size()==){
  45. for(int i=cost[x];i<=M;i++) f[x][i]=val[x];
  46. return ;
  47. }
  48. for(int i=;i<son[x].size();i++) calc(son[x][i]);
  49.  
  50. for(int i=;i<son[x].size();i++){
  51. int y=son[x][i];
  52. for(int tot=M;tot>=;tot--){
  53. for(int j=;j<=tot;j++){
  54. f[x][tot]=max(f[x][tot],f[x][tot-j]+f[y][j]);
  55. }
  56. }
  57. }
  58. for(int i=M;i>=;i--){
  59. if(i>=cost[x]) f[x][i]=f[x][i-cost[x]]+val[x];
  60. else f[x][i]=;
  61. }
  62. }
  63. int main(){
  64. scanf("%d%d",&N,&M);
  65. for(int i=;i<=N;i++) scanf("%d",&W[i]);
  66. for(int i=;i<=N;i++) scanf("%d",&V[i]);
  67. for(int i=;i<=N;i++){
  68. scanf("%d",&fa[i]);
  69. to[fa[i]].push_back(i);
  70. }
  71. memset(dfn,-,sizeof(dfn));
  72. for(int i=;i<=N;i++){
  73. if(dfn[i]==-) tarjan(i);
  74. }
  75. for(int i=;i<=tot;i++){
  76. int y=kin[i][];
  77. if(kin[i].size()>=){//形成一个环 ,取其中任意一点,缩环为点
  78. val[y]=V[y]; cost[y]=W[y];
  79. son[].push_back(y);
  80. for(int j=;j<kin[i].size();j++){
  81. val[y]+=V[kin[i][j]];
  82. cost[y]+=W[kin[i][j]];
  83. }
  84. }
  85. else{//是一棵树上的某一点,直接复制
  86. if(fa[y]==)
  87. son[].push_back(y);
  88. else{
  89. int xx=inkin[fa[y]];
  90. int yy=kin[xx][];
  91. son[yy].push_back(y);
  92. }
  93. val[y]=V[y]; cost[y]=W[y];
  94. }
  95. }
  96. val[]=; cost[]=; calc();
  97. printf("%d",f[][M]);
  98. return ;
  99. }

cogs 444. [HAOI2010]软件安装的更多相关文章

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

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

  2. 【BZOJ2427】[HAOI2010]软件安装(动态规划,Tarjan)

    [BZOJ2427][HAOI2010]软件安装(动态规划,Tarjan) 题面 BZOJ 洛谷 题解 看到这类题目就应该要意识到依赖关系显然是可以成环的. 注意到这样一个性质,依赖关系最多只有一个, ...

  3. 洛谷 P2515 [HAOI2010]软件安装 解题报告

    P2515 [HAOI2010]软件安装 题目描述 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到 ...

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

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

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

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

  6. Tarjan+树形DP【洛谷P2515】[HAOI2010]软件安装

    [洛谷P2515][HAOI2010]软件安装 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得 ...

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

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

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

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

  9. HAOI2010软件安装(树形背包)

    HAOI2010软件安装(树形背包) 题意 有n个物品,每个物品最多会依赖一个物品,但一个物品可以依赖于一个不独立(依赖于其它物品)的物品,且可能有多个物品依赖一个物品,并且依赖关系可能形成一个环.现 ...

随机推荐

  1. jdb--gdb---java 远程调试(java application与web application)

    命令比较     gdb              jdb     bt             where     del           clear     stop         brea ...

  2. 青蛙的约会---poj1061(扩展欧几里德)

    题目链接:http://poj.org/problem?id=1061 就是找到满足 (X+mt)-(Y+nt) = Lk 的 t 和 k 即可 上式可化简为 (n-m)t + Lk = X-Y;满足 ...

  3. dedecms建的网站如何去掉/index.html

    DEDECMS建立的网站,www.abc.com/index.html和www.abc.com两个都可以访问,而且两个页面都是一样的,这样就会造成重复页面,对搜索引擎不友好,那么怎么去掉index.h ...

  4. mac版 android studio问题解决

    1.mac安装android studio 解决方案:如果你是安装新手,可以下载androud studio boundls 和 安装环境的jdk就可以了,不需要单独在配置环境了,如果你有经验,可以单 ...

  5. MYSQL常见的可优化点

    MYSQL常见的可优化点 SQL常见的可优化点 2014年6月8日 DBA 发表回复 # #################################################### 索引 ...

  6. 上传指定url文件到阿里云oss

    好处是不用下载到本地,也不用删除本地文件.省事! 先下载阿里云官方代码  https://github.com/aliyun/aliyun-oss-csharp-sdk 引用其中的 aliyun-os ...

  7. Python中的__init__.py的作用

    当用 import 导入该目录时,会执行 __init__.py 里面的代码 因此在__init__.py文件中,把深层的包的路径缩短,别的地方就可以在引用到目录级别时引到深层的包.

  8. Hadoop 之日志管理—应用在 YARN 中运行时的日志

    背景: 在写这篇博文前,自己一直没有弄明白一个问题,“在 Map 函数和 Reduce 函数中使用 System.out.print 打印日志时,输出内容在哪里显示?”.试了好多回,在 log/* 目 ...

  9. PAT Product of Polynomials[一般]

    1009 Product of Polynomials (25)(25 分) This time, you are supposed to find A*B where A and B are two ...

  10. [LeetCode] 183. Customers Who Never Order_Easy tag: SQL

    Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL qu ...