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; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!