首先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. MyBatis-plus 新增实例,主键ID从很大的数字开始

    mybatis-plus是mybatis增强版,用mybatis-plus可以省去很多DAO层代码和数据库操作语句的编写.但是需要我们配置好条件. 情景: 向数据库新增一条实例,我们要调用 inser ...

  2. java面试1

    1.面向对象的特征·有·哪些方面 1)抽象 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽 ...

  3. Spring讲解-----------表达式语言

    转自:https://blog.csdn.net/u011225629/article/details/47143083 5.1  概述5.1.1  概述       Spring表达式语言全称为“S ...

  4. 查看TensorFlow的版本以及安装路径

    查看TensorFlow的版本以及安装路径 进入到Python环境 import tensorflow as tf tf.__version__ # 查看版本 tf.__path__ # 查看安装路径 ...

  5. 【JAVASCRIPT】call和apply的用法以及区别

    function add(c,d){ return this.a + this.b + c + d; } var s = {a:"鸡", b:"你"}; con ...

  6. 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)

    链接:https://ac.nowcoder.com/acm/contest/392/C 来源:牛客网 华华给月月出题 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...

  7. K nearest neighbor cs229

    vectorized code 带来的好处. import numpy as np from sklearn.datasets import fetch_mldata import time impo ...

  8. USRPX310 在GNU Radio上更改通道A或B

    UHD:USRP sink和USRP source默认是A通道发射接收.或设置 Mb0:Subdev Spec: A:0 更改为B通道收发:设置 Mb0:Subdev Spec: B:0

  9. 差分约束详解&&洛谷SCOI2011糖果题解

    差分约束系统: 如果一个系统由n个变量和m个约束条件组成,形成m个形如ai-aj≤k的不等式(i,j∈[1,n],k为常数),则称其为差分约束系统(system of difference const ...

  10. 安装Angulr CLI

    参考文档 https://www.jianshu.com/p/327d88284abb http://blog.csdn.net/zhy13087344578/article/details/6074 ...