• 【BZOJ2427】【HAOI2010】软件安装


    无力吐槽……

    原题:

    现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

    但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0

    我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

    0<=N<=100, 0<=M<=500

    恩这道题刚开始的时候我是有思路的,就是树上有限制的背包嘛

    但是为了防止写了数h+然后发现思路歪了还是去看了一下题解,然后才发现题中可以有环

    环之间相互依赖,要选一个则其它必选,就可以直接看成一个点

    然后就是tarjian缩强连通分量辣(环也是强连通分量

    但是晚上调了1h+,知道错误在哪里但是怎么都想不明白为什么,因为很晚了急着走所以就去网上对着AC代码改程序过掉了,然而依旧不能想明白为什么,电脑关机一下错误的代码也没有了,心好累,感觉应该想不明白这个问题了

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int oo=168430090;
     8 int rd(){int z=0,mk=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mk;
    12 }
    13 struct ddd{int nxt,y;}e[5100000];  int lk[1100000],ltp=0,indgr[210];
    14 inline void ist(int x,int y){  e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y,++indgr[y];}
    15 int n,m;
    16 int w[210],v[210];
    17 int dfn[210],low[210],dfscnt=0;
    18 int stck[210],tp=0;  bool vstd[210];
    19 int grp[210],grpcnt=0;
    20 int f[210][510];
    21 bool flg[210];
    22 void tj(int x){
    23     flg[x]=true;
    24     dfn[x]=low[x]=++dfscnt;
    25     stck[++tp]=x,vstd[x]=true;
    26     for(int i=lk[x];i;i=e[i].nxt){
    27         if(!dfn[e[i].y]){  tj(e[i].y);  low[x]=min(low[x],low[e[i].y]);}
    28         else if(vstd[e[i].y])  low[x]=min(low[x],dfn[e[i].y]);
    29     }
    30     if(dfn[x]==low[x]){
    31         ++grpcnt;  int tmp;
    32         do{  tmp=stck[tp--],vstd[tmp]=false,grp[tmp]=grpcnt+n;}while(tmp!=x);
    33     }
    34 }
    35 void dfs(int x){
    36     for(int i=lk[x];i;i=e[i].nxt){
    37         dfs(e[i].y);
    38         for(int j=m;j>=0;--j)for(int k=j;k>=0;--k)
    39             f[x][j]=max(f[x][j],f[x][j-k]+f[e[i].y][k]);
    40     }
    41     for(int i=m;i>=w[x];--i)  f[x][i]=f[x][i-w[x]]+v[x];
    42     for(int i=0;i<w[x];++i)  f[x][i]=0;
    43 }
    44 int main(){//freopen("ddd.in","r",stdin);
    45     memset(vstd,0,sizeof(vstd));
    46     memset(f,0,sizeof(f));
    47     memset(flg,0,sizeof(flg));
    48     cin>>n>>m;
    49     for(int i=1;i<=n;++i)  w[i]=rd();
    50     for(int i=1;i<=n;++i)  v[i]=rd();
    51     for(int i=1;i<=n;++i)  ist(rd(),i);
    52     for(int i=1;i<=n;++i)if(!dfn[i])  tj(i);
    53     for(int i=1;i<=n;++i){
    54         w[grp[i]]+=w[i],v[grp[i]]+=v[i];
    55         for(int j=lk[i];j;j=e[j].nxt)if(grp[e[j].y]!=grp[i])
    56             ist(grp[i],grp[e[j].y]);
    57     }
    58     for(int i=1;i<=grpcnt;++i)if(!indgr[i+n])  ist(grpcnt+n+1,i+n);
    59     dfs(grpcnt+n+1);
    60     int mx=0;
    61     for(int i=0;i<=m;++i)  mx=max(mx,f[grpcnt+n+1][i]);
    62     cout<<mx<<endl;
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    成功引爆
    pecompact2脱壳手记
    象棋
    今天小雨
    出错了,怎么办?
    设计模式——Adapter模式
    表设计中应注意的2点
    设计模式——Singleton模式
    设计模式——Facade模式
    设计模式——Strategy模式
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6533857.html
Copyright © 2020-2023  润新知