洛谷 P2515 [HAOI2010]软件安装
来源:互联网 发布:塔吉特百货大数据 编辑:程序博客网 时间:2024/06/06 19:03
题目描述
现在我们的手头有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 105 5 62 3 40 1 1
输出样例#1:
5
哈哈,又是一道好题!
思路还是比较好想的,先tarjan缩点,重新建图,原图从基环树变成树,做树形dp,然而本人比较弱,树形dp没有一次写对。
#include<iostream>#include<cstring>#include<cstdio>#include<stack>using namespace std;const int N=105;int n,m,cnt,dcnt,tim,d[N],c[N],w[N],hd[N],dfn[N],low[N],cc[N],ww[N],f[N][505],belong[N],du[N];bool ins[N];stack<int>stk;struct edge{int to,nxt;}v[N];void addedge(int x,int y){v[++cnt].to=y;v[cnt].nxt=hd[x];hd[x]=cnt;}void tarjan(int u){dfn[u]=low[u]=++tim;ins[u]=1;stk.push(u);for(int i=hd[u];i;i=v[i].nxt){if(!dfn[v[i].to]){tarjan(v[i].to);low[u]=min(low[u],low[v[i].to]);}else if(ins[v[i].to])low[u]=min(low[u],dfn[v[i].to]);}if(dfn[u]==low[u]){++dcnt;while(1){int t=stk.top();stk.pop();ins[t]=0;belong[t]=dcnt;if(u==t)break;}}}void dp(int u,int fa){for(int i=hd[u];i;i=v[i].nxt)if(v[i].to!=fa){dp(v[i].to,u);for(int j=m-cc[u];j>=1;j--)for(int k=1;k<=j;k++)f[u][j]=max(f[u][j],f[u][j-k]+f[v[i].to][k]);}for(int i=m;i>=0;i--)if(i>=cc[u])f[u][i]=f[u][i-cc[u]]+ww[u];elsef[u][i]=0;}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&c[i]);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++){scanf("%d",&d[i]);if(d[i])addedge(d[i],i);}//缩点 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);//重新建图 for(int i=1;i<=n;i++)cc[belong[i]]+=c[i],ww[belong[i]]+=w[i];memset(hd,0,sizeof(hd));cnt=0;for(int i=1;i<=n;i++)if(d[i]&&belong[d[i]]!=belong[i]){addedge(belong[d[i]],belong[i]);du[belong[i]]++;}for(int i=1;i<=dcnt;i++)if(!du[i])addedge(0,i);//树形dp dp(0,-1);printf("%d\n",f[0][m]);return 0;}
0 0
- 洛谷 P2515 [HAOI2010]软件安装
- 洛谷 P2515 [HAOI2010]软件安装
- BZOJ2427 洛谷P2515 [HAOI2010]软件安装
- codevs1866(洛谷p2515)软件开发【HAOI2010】
- bzoj2427: [HAOI2010]软件安装
- 软件安装 [HAOI2010,Bzoj2427]
- BZOJ2427: [HAOI2010]软件安装
- [HAOI2010] 软件安装
- [HAOI2010]软件安装
- 2427: [HAOI2010]软件安装
- [HAOI2010]软件安装
- 【bzoj2427】[HAOI2010]软件安装
- bzoj 2427[HAOI2010] 软件安装
- BZOJ 2427: [HAOI2010]软件安装
- BZOJ 2427: [HAOI2010]软件安装
- 【bzoj2427】【HAOI2010】【软件安装】【缩点+dp】
- [bzoj2427][HAOI2010]软件安装 Tarjan+树形DP
- BOZJ 2427: [HAOI2010]软件安装 树形背包
- CodeForces779C--Dishonest Sellers
- Android 统一为项目中的所有 Activity 添加自定义TopBar
- Linux学习之第十三章
- oracle创建数据库 表空间 用户
- AndroidStudio将module变为library
- 洛谷 P2515 [HAOI2010]软件安装
- CSS+HTML实现梅兰商贸网页设计
- Linux常用命令
- 文章标题
- 常见的数据结构和算法
- android sqlite 初次尝试遇到的坑
- 基于MCS-51内核的汇编-子程序设计
- #7 D. Palindrome Degree (manacher + dp)
- zoj 3777【状态压缩dp】