【BZOJ-2427】软件安装 Tarjan + 树形01背包
2427: [HAOI2010]软件安装
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 960 Solved: 380
[Submit][Status][Discuss]
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
Solution
把环缩成一个点...
建立超级根0....
然后树形01背包
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 110
#define MAXM 510
struct EdgeNode{int next,to;}edge[MAXN<<],road[MAXN<<];
int head[MAXN],cnt=,first[MAXN],tot=;
inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
inline void InsertEdge(int u,int v) {if (!u) return; AddEdge(u,v);}
int w[MAXN],v[MAXN],V[MAXN],W[MAXN],N,M;
int dfn[MAXN],low[MAXN],st[MAXN],top,visit[MAXN],belong[MAXN],size[MAXN],dfsn,scc;
inline void Tarjan(int x)
{
dfn[x]=low[x]=++dfsn; visit[x]=; st[++top]=x;
for (int i=head[x]; i; i=edge[i].next)
if (!dfn[edge[i].to]) Tarjan(edge[i].to),low[x]=min(low[x],low[edge[i].to]);
else if (visit[edge[i].to]) low[x]=min(dfn[edge[i].to],low[x]);
if (dfn[x]==low[x])
{
int stp=;
scc++;
while (x!=stp) stp=st[top--],size[scc]++,W[scc]+=w[stp],V[scc]+=v[stp],belong[stp]=scc,visit[stp]=;
}
}
inline void AddRoad(int u,int v) {tot++; road[tot].next=first[u]; first[u]=tot; road[tot].to=v;}
inline void InsertRoad(int u,int v) {AddRoad(u,v); AddRoad(v,u);}
bool flag[MAXN];
inline void Rebuild()
{
for (int i=; i<=N; i++)
for (int j=head[i]; j; j=edge[j].next)
if (belong[i]!=belong[edge[j].to])
InsertRoad(belong[i],belong[edge[j].to]),flag[belong[edge[j].to]]=;
for (int i=; i<=scc; i++) if (!flag[i]) InsertRoad(,i);
}
int f[MAXN][MAXM],g[MAXN][MAXM];
void DP(int x,int last)
{
for (int i=first[x]; i; i=road[i].next)
if (road[i].to!=last)
{
DP(road[i].to,x);
for (int j=M-W[x]; j>=; j--)
for (int k=; k<j; k++)
g[x][j]=max(g[x][j],g[x][k]+f[road[i].to][j-k]);
}
for (int i=; i<=M-W[x]; i++) f[x][i+W[x]]=g[x][i]+V[x];
}
int main()
{
N=read(),M=read();
for (int i=; i<=N; i++) w[i]=read();
for (int i=; i<=N; i++) v[i]=read();
for (int f,i=; i<=N; i++) f=read(),InsertEdge(f,i);
for (int i=; i<=N; i++) if (!dfn[i]) Tarjan(i);
Rebuild();
DP(,);
printf("%d\n",f[][M]);
return ;
}
【BZOJ-2427】软件安装 Tarjan + 树形01背包的更多相关文章
- bzoj 2427 软件安装 - Tarjan - 树形动态规划
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- BZOJ 2427: [HAOI2010]软件安装 tarjan + 树形背包
Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和 ...
- BZOJ 2427 软件安装(强连通分量+树形背包)
题意:现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大).但是现在有 ...
- 【bzoj2427】[HAOI2010]软件安装 Tarjan+树形背包dp
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大).但是现 ...
- 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
[BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...
- [BZOJ 2427] 软件安装
Link: BZOJ 2427 传送门 Solution: 只看样例的话会以为是裸的树形$dp$…… 但实际上题目并没有说明恰好仅有一个物品没有依赖项 因此原图可能由是由多棵树与多个图组成的 先跑一遍 ...
- BZOJ2427: [HAOI2010]软件安装 tarjan+树形背包
分析: 一开始我以为是裸的树形背包...之后被告知这东西...可能有环...什么!有环! 有环就搞掉就就可以了...tarjan缩点...建图记得建立从i到d[i]之后跑tarjan,因为这样才能判断 ...
- [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)
如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...
- BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP
BZOJ_2427_[HAOI2010]软件安装_tarjan+树形DP 题意: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁 ...
随机推荐
- django复习笔记2:models
关于models,主要想说的是django shell以及生成测试数据的脚本这两部分. 一个models中的类相当于数据库的一张表,先看一个设置了外键的models. from django.db i ...
- Codevs 1860 最大数 string大法好,STL万岁。。
题目描述 Description 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 输入描述 Input Description 第一行一个正整数n. 第二行n个正整数,空格隔开 ...
- Ninject 学习杂记
IOC容器的DI实现并不依赖于方法调用拦截,而是通过DI容器内部自己通过反射的方式生成需要的类型实例,并调用实例的成员.然后再把实例返回给容器外部环境使用. Ninject本身及其扩展库,还针对特定的 ...
- 1002. A+B for Polynomials
1002. A+B for Polynomials (25) This time, you are supposed to find A+B where A and B are two polynom ...
- NOI2018准备 Day8
清北学堂入学测试,6道题凑了363分,平均466才能达到省选班的程度,差距不小. 今天突然感觉最大的BOSS是搜索,虽然每次都写崩...... 3个小时写了一道DP没写出来 但我不会忘记,我的首个目标 ...
- 关于Microsoft Visual Studio 2010系统自带的数据库
转自:http://blog.sina.com.cn/s/blog_a570cca601012x5w.html 1.Visual studio Tools>命令提示 2.aspnet_regsq ...
- warning: #870-D: invalid multibyte character sequence
warning: #870-D: invalid multibyte character sequence2011-03-12 9:18warning: #870-D: invalid multiby ...
- 发布了Android的App,我要开源几个组件!
做了一款App,本来是毕业设计但是毕业的时候还没有做完,因为大部分时间都改论文去了,你们都懂的.现在毕业了在工作之余把App基本上做完了.为什么说基本上呢,因为我觉得还有很多功能还没实现,还要很多bu ...
- Qt中forward declaration of struct Ui::xxx的解决
每当你新键一个 QT设计界面, QT会自动生成yyy.ui文件,如 <?xml version="1.0" encoding="UTF-8"?> & ...
- WebService的两种方式SOAP和REST比较 (转)
我的读后感:由于第一次接触WebService,对于很多概念不太理解,尤其是看到各个OpenAPI的不同提供方式时,更加疑惑.如google map api采用了AJAX方式,通过javascript ...