zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    LC 面试题56
    AspNet 执行存储过程带参数 and Entity Framework 之存储过程篇
    SQL中Charindex和Oracle中对应的函数Instr
    Spring MVC遭遇checkbox的问题解决方案
    Spring MVC 的 multipartResolver 不能同iWebOffice2006 共同使用
    Spring CommonsMultipartResolver 上传文件
    解决自定义文件上传处理与Spring MultipartResolver的冲突问题
    GooFlow
    js判断undefined类型
    mybatis generator tools配置文件解析
  • 原文地址:https://www.cnblogs.com/zzyer/p/8560697.html
Copyright © 2011-2022 走看看