首先tarjan缩点应该能看出来,然后我用topsort跑了个DAG上的一维dp,结果WA的很惨。

其实用DAG应该也能做,但是DAG强调整体顺序,而对一些局部问题,例如两个儿子怎么分配,是否给当前节点分配,那就太粗略化了,导致错误。

正确的姿势是把所有没有入度的点接到虚根上,因为tarjan缩完很可能是个森林,剩下的就是跑树形依赖的背包了。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<map>
using namespace std;
struct EDGE{
int ed,nex;
}edge[],edgec[];int num,numc,first[],firstc[];
int read(){
int sum=,f=;char x=getchar();
while(x<''||x>''){
if(x=='-') f=-;
x=getchar();
}while(x>=''&&x<=''){
sum=sum*+x-'';
x=getchar();
}return sum*f;
}
int n,m,w[],v[],dp[][];
int dfn[],low[],ord;
int stack[],top,ans,root;
int sccnum,bl[];
vector<int>scc[];
int wc[],vc[],du[];
bool ins[];
void add(int st,int ed){
edge[++num].ed=ed;
edge[num].nex=first[st];
first[st]=num;
}
void addc(int st,int ed){
edgec[++numc].ed=ed;
edgec[numc].nex=firstc[st];
firstc[st]=numc;
}
void tarjan(int x){
dfn[x]=low[x]=++ord;
stack[++top]=x;ins[x]=;
for(int i=first[x];i;i=edge[i].nex){
int y=edge[i].ed;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(ins[y])
low[x]=min(low[x],dfn[y]);
}if(low[x]==dfn[x]){
sccnum++;int p;
do{
p=stack[top--];ins[p]=;
bl[p]=sccnum;scc[sccnum].push_back(p);
}while(x!=p);
}
} void dfs(int x){
//cout<<"fa="<<x<<endl;
/* for(int i=firstc[x];i;i=edgec[i].nex){
int y=edgec[i].ed;
cout<<y<<" ";
}*/
for(int i=firstc[x];i;i=edgec[i].nex){
int y=edgec[i].ed;
dfs(y);
for(int j=m-wc[x];j>=;j--)
for(int k=;k<=j;k++)
dp[x][j]=max(dp[x][j],dp[x][k]+dp[y][j-k]);
}
for(int i=m;i>=wc[x];i--) dp[x][i]=dp[x][i-wc[x]]+vc[x];
for(int i=;i<wc[x];i++) dp[x][i]=;
}
int main(){
/*freopen("9.in","r",stdin);
freopen("9.out","w",stdout);*/
/* memset(dp,0xcf,sizeof(dp));
dp[0]=0;*/
n=read();m=read();
for(int i=;i<=n;i++) w[i]=read();
for(int i=;i<=n;i++) v[i]=read();
for(int i=,D;i<=n;i++){
D=read();
if(!D) continue;
add(D,i);
}
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<=sccnum;i++)
for(int j=;j<scc[i].size();j++)
wc[i]+=w[scc[i][j]],vc[i]+=v[scc[i][j]];
for(int i=;i<=n;i++){
for(int j=first[i];j;j=edge[j].nex){
int y=edge[j].ed;
if(bl[i]==bl[y]) continue;
addc(bl[i],bl[y]);
// cout<<"St="<<bl[i]<<" Ed="<<bl[y]<<endl;
du[bl[y]]++;
}
}
root=sccnum+;
for(int i=;i<=sccnum;i++)
if(!du[i]) addc(root,i);
/* for(int i=1;i<=numc;i++)
cout<<edgec[i].ed<<" "<<edgec[i].nex<<endl;*/
/* for(int i=1;i<=sccnum;i++){
for(int j=0;j<scc[i].size();j++)
cout<<scc[i][j]<<" ";
cout<<endl;
}
for(int i=1;i<=sccnum;i++)
cout<<wc[i]<<" "<<vc[i]<<endl;*/
/* for(int i=1;i<=n;i++)
cout<<bl[i]<<" ";cout<<endl;
for(int i=1;i<=sccnum;i++)
cout<<wc[i]<<" "<<vc[i]<<endl;
for(int i=1;i<=numc;i++)
cout<<edgec[i].st<<" "<<edgec[i].ed<<endl;*/
dfs(root);
/* for(int i=0;i<=m;i++)
cout<<dp[root][i]<<" ";cout<<endl;*/
printf("%d",dp[root][m]);cout<<endl;
return ;
}

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个物品,每个物品最多会依赖一个物品,但一个物品可以依赖于一个不独立(依赖于其它物品)的物品,且可能有多个物品依赖一个物品,并且依赖关系可能形成一个环.现 ...

  10. [HAOI2010]软件安装(Tarjan,树形dp)

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

随机推荐

  1. C#取绝对值函数

    System.Math.Abs(float value); System.Math.Abs(decimal value); System.Math.Abs(int value); System.Mat ...

  2. JavaSE基础知识之多态

    一. 概述 多态是继封装.继承之后,面向对象的第三大特性,指同一行为,具有多个不同表现形式.生活中,比如跑的动作,小猫.小狗和大象,跑起来是不一样的.再比如飞的动作,昆虫.鸟类和飞机,飞起来也是不一样 ...

  3. 三、maven学习-高级

    maven父子工程

  4. input 禁止输入特殊字符

    方式一:拿到value值以后 在你传递之前处理 function stripscript(value) { var pattern = new RegExp("[`~!@#$^&*( ...

  5. vue入门:(class与style绑定)

    对象语法 数组语法 一.对象语法 1.1对象语法绑定HTML Class 语法:v-bind:class="{'className1':boolean1,'className2':boole ...

  6. SSIS 初次接触 + 开发记录

    第一次接触SSIS,昨天终于把一套流程走通,记一下流水. 1:安装 使用SSIS需要安装插件(VS 和Sql Server都需要另外安装). 自己使用的vs2017开发,官网有专门的 VS2017 安 ...

  7. centos 7 OpenResty®(lua-nginx-module)搭建可扩展的Web平台

    OpenResty®-英文官网地址:http://openresty.org/en/ OpenResty®-中文官网地址: http://openresty.org/cn/ OpenResty®> ...

  8. NORDIC 修改MTU

    https://www.cnblogs.com/jiangjiu/p/10063556.html 注意要修改RAM起始地址,因为MTU增大了

  9. unix/linux共享库(动态库)简介

    一.创建共享库: 1.写源程序 xxx1.c xxx2.c.../*.c(通配符方式) 2.编译源程序,加-fpic生成.o文件 gcc -c -fpic xxx1.c xxx2.c.../*.c(通 ...

  10. 3.NIO_Buffer缓冲区

    1.缓冲区(Buffer) 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类,任何时候访问 NIO 中 的数据,都是通过缓冲区进行操作 在 J ...