zoukankan      html  css  js  c++  java
  • bzoj 2427 [HAOI2010]软件安装 Tarjan缩点+树形dp

    [HAOI2010]软件安装

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2029  Solved: 811
    [Submit][Status][Discuss]

    Description

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

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

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

    Input

    第1行:N, M  (0<=N<=100, 0<=M<=500)
          第2行:W1, W2, ... Wi, ..., Wn (0<=Wi<=M )
          第3行:V1, V2, ..., Vi, ..., Vn  (0<=Vi<=1000 )
          第4行:D1, D2, ..., Di, ..., Dn (0<=Di<=N, Di≠i )

    Output

    一个整数,代表最大价值。

    Sample Input

    3 10
    5 5 6
    2 3 4
    0 1 1

    Sample Output

    5

    HINT

     
    树形,dp依赖型的,算完点,是一棵树对吧,然后就从根向下dp数据范围如此之小。
    f[i][j]表示i这个点,可以用安装连续几个点的方案数。
     
      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 
      7 #define N 107
      8 #define M 507
      9 using namespace std;
     10 inline int read()
     11 {
     12     int x=0,f=1;char ch=getchar();
     13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 
     18 int n,m,cnt,scc,ind,top;
     19 int v[N],w[N];
     20 int sv[N],sw[N];
     21 int dfn[N],low[N],belong[N];
     22 int q[N],f[N][M],in[M];
     23 struct edge{
     24     int to,next;
     25 }e[M],ed[M];int last[N],last2[N];
     26 bool inq[N];
     27 
     28 void insert(int u,int v){e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;}
     29 void insert2(int u,int v)
     30 {
     31     in[v]=1;
     32     ed[++cnt].to=v;ed[cnt].next=last2[u];last2[u]=cnt;
     33 }
     34 void tarjan(int x)
     35 {
     36     int now=0;
     37     low[x]=dfn[x]=++ind;
     38     q[++top]=x;inq[x]=1;
     39     for(int i=last[x];i;i=e[i].next)
     40         if(!dfn[e[i].to])
     41         {
     42             tarjan(e[i].to);
     43             low[x]=min(low[x],low[e[i].to]);
     44         }
     45         else if(inq[e[i].to])
     46             low[x]=min(low[x],dfn[e[i].to]);
     47     if(low[x]==dfn[x])
     48     {
     49         scc++;
     50         while(now!=x)
     51         {
     52             now=q[top--];inq[now]=0;
     53             belong[now]=scc;
     54             sv[scc]+=v[now];
     55             sw[scc]+=w[now];
     56         }
     57     }
     58 }
     59 void rebuild()
     60 {
     61     cnt=0;
     62     for(int x=1;x<=n;x++)
     63         for(int i=last[x];i;i=e[i].next)
     64             if(belong[e[i].to]!=belong[x])
     65                 insert2(belong[x],belong[e[i].to]);
     66 }
     67 void dp(int x)
     68 {
     69     for(int i=last2[x];i;i=ed[i].next)
     70     {
     71         dp(ed[i].to);
     72         for(int j=m-sw[x];j>=0;j--)
     73         {
     74             for(int k=0;k<=j;k++)
     75                 f[x][j]=max(f[x][j],f[x][k]+f[ed[i].to][j-k]);        
     76         }
     77     }
     78     for(int j=m;j>=0;j--)
     79     {
     80         if(j>=sw[x])f[x][j]=f[x][j-sw[x]]+sv[x];
     81         else f[x][j]=0;
     82     }
     83 }
     84 int main()
     85 {
     86     n=read();m=read();
     87     for(int i=1;i<=n;i++) w[i]=read();
     88     for(int i=1;i<=n;i++) v[i]=read();
     89     for(int i=1;i<=n;i++)
     90     {
     91         int x=read();
     92         if(x)insert(x,i);
     93     }
     94     for(int i=1;i<=n;i++)
     95         if(!dfn[i])tarjan(i);
     96     rebuild();
     97     for(int i=1;i<=scc;i++)
     98         if(!in[i])
     99             insert2(scc+1,i);
    100     dp(scc+1);
    101     printf("%d
    ",f[scc+1][m]);
    102 }
     
  • 相关阅读:
    python模块
    python函数进阶
    python函数
    六.python的深浅拷贝
    五.集合及其推导式
    IOS微信显示NAN,中国标准时间日期转换
    Caused by: org.apache.ibatis.binding.BindingException: Parameter 'XXX' not found. Available parameters are [beginTime, endTime, param3, param1, vesselName, param2] 找不到参数的解决方式
    java的nullpointerexception空指针异常,关于使用了timer定时导致service调用问题
    java设置开始时间,定时执行任务
    java多层嵌套集合的json,如何获取多层集合中所需要的value
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8745951.html
Copyright © 2011-2022 走看看