• bzoj2427[HAOI2010]软件安装


    bzoj2427[HAOI2010]软件安装

    题意:

    有n个软件,每个大小为wi,价值为vi,同时每个软件依赖0个或一个其他软件,要求在大小不超过的m的前提下得到最大价值。n≤100,m≤500。

    题解:

    缩点然后做“树上背包dp”,具体看代码,注意里面用到了滚动数组。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define dec(i,j,k) for(int i=j;i>=k;i--)
     6 #define maxn 150
     7 using namespace std;
     8 
     9 int bel[maxn],scc,dfn[maxn],low[maxn],tim,st[maxn],top,sv[maxn],sw[maxn],v[maxn],w[maxn]; bool inst[maxn],ok[maxn];
    10 struct e1{int f,t,n;}; e1 es1[maxn*5]; int g1[maxn],ess1;
    11 void pe1(int f,int t){es1[++ess1]=(e1){f,t,g1[f]}; g1[f]=ess1;}
    12 struct e2{int t,n;}; e2 es2[maxn*10]; int g2[maxn],ess2;
    13 void pe2(int f,int t){es2[++ess2]=(e2){t,g2[f]}; g2[f]=ess2; ok[t]=1;}
    14 void init(){
    15     ess1=ess2=0; memset(g1,0,sizeof(g1)); memset(g2,0,sizeof(g2));
    16     tim=scc=0; memset(inst,0,sizeof(inst)); memset(dfn,0,sizeof(dfn));
    17 }
    18 void tarjan(int x){
    19     dfn[x]=low[x]=++tim; st[++top]=x; inst[x]=1;
    20     for(int i=g1[x];i;i=es1[i].n){
    21         if(!dfn[es1[i].t]){
    22             tarjan(es1[i].t); low[x]=min(low[x],low[es1[i].t]);
    23         }else if(inst[es1[i].t])low[x]=min(low[x],dfn[es1[i].t]);
    24     }
    25     if(dfn[x]==low[x]){
    26         scc++; int y=0; while(x!=y)y=st[top],bel[y]=scc,sv[scc]+=v[y],sw[scc]+=w[y],inst[y]=0,top--;
    27     }
    28 }
    29 void build(){inc(i,1,ess1)if(bel[es1[i].f]!=bel[es1[i].t])pe2(bel[es1[i].f],bel[es1[i].t]);}
    30 int f[maxn][maxn*5],n,m;
    31 void dfs(int x){
    32     for(int i=g2[x];i;i=es2[i].n){
    33         dfs(es2[i].t);
    34         dec(j,m-sw[x],0)inc(k,0,j)f[x][j]=max(f[x][j],f[x][k]+f[es2[i].t][j-k]);
    35     }
    36     dec(j,m,0)if(j>=sw[x])f[x][j]=f[x][j-sw[x]]+sv[x];else f[x][j]=0;
    37 }
    38 inline int read(){
    39     char ch=getchar(); int f=1,x=0;
    40     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    41     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    42     return f*x;
    43 }
    44 int main(){
    45     n=read(); m=read(); inc(i,1,n)w[i]=read(); inc(i,1,n)v[i]=read(); init();
    46     inc(i,1,n){int a=read(); if(a)pe1(a,i);} inc(i,1,n)if(!dfn[i])tarjan(i); build();
    47     inc(i,1,scc)if(!ok[i])pe2(scc+1,i); dfs(scc+1); printf("%d",f[scc+1][m]); return 0;
    48 }

    20160614

  • 相关阅读:
    Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)
    MySQL 数据备份与还原
    java实现时钟方法汇总
    java实现二叉树demo
    java实现心型、99乘法demo
    显示本月日历demo
    打开图片并显示在面板上demo
    ArraySort--冒泡排序、选择排序、插入排序工具类demo
    类的实例化顺序
    StringsUtil字符串工具类---灵活截取
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5779844.html
Copyright © 2020-2023  润新知