BZOJ 2427 [HAOI2010]软件安装
题解:
在一个环内的软件要么都安要么都不安
先缩点,然后这是一棵树
树形背包即可

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2009;
int n,m;
int inw[maxn],inv[maxn],b[maxn];
int cntedge=0;
int head[maxn]={0};
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
}
int dfsclock,scccnt;
int sccno[maxn],pre[maxn],lowlink[maxn];
int Sta[maxn],top=0;
void Dfs(int u){
pre[u]=lowlink[u]=++dfsclock;
Sta[++top]=u;
int v=b[u];
if(!v){
}else if(!pre[v]){
Dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}else if(!sccno[v]){
lowlink[u]=min(lowlink[u],pre[v]);
}
if(lowlink[u]==pre[u]){
++scccnt;
for(;;){
int x=Sta[top--];
sccno[x]=scccnt;
if(x==u)break;
}
}
}
int w[maxn]={0},v[maxn]={0};
int father[maxn]={0};
void Tarjan(){
for(int i=1;i<=n;++i)if(!pre[i])Dfs(i);
for(int i=1;i<=n;++i){
w[sccno[i]]+=inw[i];
v[sccno[i]]+=inv[i];
if(!b[i])continue;
if(sccno[i]!=sccno[b[i]]){
Addedge(sccno[b[i]],sccno[i]);
father[sccno[i]]=sccno[b[i]];
}
}
}
int f[maxn][maxn];
void Dp(int x){
for(int i=head[x];i;i=nex[i]){
int v=to[i];
Dp(v);
for(int j=m;j>=0;--j){
for(int k=0;k<=j;++k){
f[x][j]=max(f[x][j],f[x][j-k]+f[v][k]);
}
}
}
for(int i=m;i>=w[x];--i)f[x][i]=f[x][i-w[x]]+v[x];
for(int i=0;i<w[x];++i)f[x][i]=0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&inw[i]);
for(int i=1;i<=n;++i)scanf("%d",&inv[i]);
for(int i=1;i<=n;++i)scanf("%d",&b[i]);
Tarjan();
for(int i=1;i<=scccnt;++i)if(!father[i])Addedge(0,i);
Dp(0);
// for(int i=0;i<=n;++i){
// for(int j=1;j<=m;++j){
// cout<<f[i][j]<<' ';
// }
// cout<<endl;
// }
for(int i=1;i<=m;++i)f[0][i]=max(f[0][i],f[0][i-1]);
cout<<f[0][m]<<endl;
return 0;
}
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!

浙公网安备 33010602011771号