• BZOJ 2427: [HAOI2010]软件安装


    题目大意:

    软件之间有依赖关系,若这款软件依赖的软件能产生贡献且这款软件被安装了则这款软件能产生vi的贡献,同时安装这款软件需要wi的内存。

    问内存不超过m时所能得到的最大贡献。

    题解:
    若依赖关系存在环,显然要使得环中的任意一个软件产生贡献必须把整个环取了。

    先缩点,把一个环当成一个物品,然后缩完点的图就是一棵树。

    树上一个点被取了,他的父亲也必须被取。

    做一遍背包就好了。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,id,ti,cnt,top,in[1000005],x[1000005],f[505][505],last[1000005],dfn[1000005],low[1000005],stack[1000005],instack[1000005],belong[1000005],sw[1000005],sv[1000005],v[1000005],w[1000005];
    struct node{
    	int to,next;
    }e[1000005];
    void add(int a,int b){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	last[a]=cnt;
    }
    void Tarjan(int x,int fa){
    	dfn[x]=low[x]=++ti;
    	stack[++top]=x;
    	instack[x]=1;
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (!dfn[V]){
    			Tarjan(V,x);
    			low[x]=min(low[x],low[V]);
    		}
    		else if (instack[V]) low[x]=min(low[x],dfn[V]);
    	}
    	if (low[x]==dfn[x]){
    		id++;
    		int now=0;
    		while (now!=x){
    			now=stack[top--];
    			instack[now]=0;
    			belong[now]=id;
    			sv[id]+=v[now];
    			sw[id]+=w[now];
    		}
    	}
    }
    void dp(int x){
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		dp(V);
    		for (int j=m-sw[x]; j>=0; j--)
    			for (int k=0; k<=j; k++)
    				f[x][j]=max(f[x][j],f[x][k]+f[V][j-k]);
    	}
    	for (int j=m; j>=0; j--){
    		if (j>=sw[x]) f[x][j]=f[x][j-sw[x]]+sv[x];
    		else f[x][j]=0;
    	}
    }
    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",&x[i]);
    		if (x[i]) add(x[i],i);
    	}
    	for (int i=1; i<=n; i++)
    		if (!dfn[i]) Tarjan(i,0);
    	cnt=0;
    	memset(last,0,sizeof(last));
    	for (int i=1; i<=n; i++)
    		if (x[i] && belong[x[i]]!=belong[i]){
    			add(belong[x[i]],belong[i]);
    			in[belong[i]]++;
    		}
    	for (int i=1; i<=id; i++)
    		if (!in[i]) {
    			add(id+1,i);
    		}
    	dp(id+1);
    	printf("%d
    ",f[id+1][m]);
    	return 0;
    }
    

      

  • 相关阅读:
    CF519E
    Visual Studio 2017更新内容记录
    MSSQL导入数据时,出现“无法截断表 因为表正由Foreign key引用”错误
    使用NeatUpload控件实现ASP.NET大文件上传
    jquery 图片无缝切换
    less 能加快css编写?
    jquery 分页控件(二)
    jquery 分页控件(一)
    jquery仿天猫商城左侧导航菜单
    jquery 图片放大
  • 原文地址:https://www.cnblogs.com/silenty/p/8893489.html
Copyright © 2020-2023  润新知