bzoj 2427[HAOI2010] 软件安装

  • Post author:
  • Post category:其他


/*强连通分量缩点,完全背包就够了*/
/*受hzwer大神的启发*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int dfn[205],low[205],head[205],tail[205],w[205],v[205],d[205],weight[205],value[205],belong[205],stack[205];
int f[205][600];
int n,m,times,top,tar_num,tot,ans;
bool vis[205],in[205];
struct dd{
	int begin,end,next;
}jie[6000];
struct df{
	int begin,end,next;
}st[6000];
void add(int x,int y){
	jie[++tot].begin=x; jie[tot].end=y; jie[tot].next=head[x]; head[x]=tot;
}
void add2(int x,int y){
	in[y]=1;
	st[++ans].begin=x;  st[ans].end=y;  st[ans].next=tail[x];  tail[x]=ans;
}
void tar(int x){
	times++;
	dfn[x]=low[x]=times; vis[x]=1; stack[++top]=x;
	for(int i=head[x];i;i=jie[i].next){
		int sto=jie[i].end;
		if(!dfn[sto]){
			tar(sto); if(low[sto]<low[x]) low[x]=low[sto];
		}
		else
		 if(vis[sto])
		  if(dfn[sto]<low[x]) low[x]=dfn[sto];
	}
	if(dfn[x]==low[x]){
		++tar_num;
		int yu;
		do{
            yu=stack[top--];
			belong[yu]=tar_num;
			weight[tar_num]+=w[yu];
			value[tar_num]+=v[yu];
			vis[yu]=0;
		}while(x!=yu);
	}
}
void getans(int x){
	for(int i=tail[x];i;i=st[i].next){
		int yu=st[i].end;
		getans(yu);
		for(int j=m-weight[x];j>=0;j--)
		 for(int k=0;k<=j;++k)
		  if(f[x][j]<f[x][k]+f[yu][j-k]) f[x][j]=f[x][k]+f[yu][j-k];
	}
	for(int i=m;i>=0;--i)
	 if(i>=weight[x]) f[x][i]=f[x][i-weight[x]]+value[x];
	 else f[x][i]=0;
}
void rebuild(){
	for(int i=1;i<=tot;++i)
	 if(belong[jie[i].begin]!=belong[jie[i].end])
	  add2(belong[jie[i].end],belong[jie[i].begin]);
	for(int i=1;i<=tar_num;++i)
	 if(!in[i]) add2(tar_num+1,i);
	getans(tar_num+1);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&w[i]);
	for(int i=1;i<=n;++i) scanf("%d",&v[i]);
	for(int i=1;i<=n;++i) scanf("%d",&d[i]);
	for(int i=1;i<=n;++i){
		if(!d[i]) continue;
		else add(i,d[i]);
	}
	for(int i=1;i<=n;++i)
	 if(!dfn[i]) tar(i);
	rebuild();
	printf("%d",f[tar_num+1][m]);
}