zoukankan      html  css  js  c++  java
  • bzoj2427

    tarjan+dp

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<ctime>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<algorithm>
     8 #include<stack>
     9 #define clr(a,x) memset(a,x,sizeof(x))
    10 #define rep(i,l,r) for(int i=l;i<r;i++)
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn=109,maxm=509;
    14 int dfn=0,cnt=1,scccnt=0,n,m,w[maxn],v[maxn],W[maxn],V[maxn],scc[maxn],low[maxn],pre[maxn],f[maxn],to[maxn];
    15 int root,d[maxn][maxm],Cnt[maxn],son[maxn][maxn];
    16 bool p[maxn];
    17 stack<int>S;
    18 void tarjan(int x){
    19     low[x]=pre[x]=++dfn;
    20     S.push(x);
    21     if(f[x]){
    22         if(!pre[f[x]]){
    23             tarjan(f[x]);
    24             low[x]=min(low[x],low[f[x]]);
    25         }else if(!scc[f[x]]) low[x]=min(low[x],pre[f[x]]);
    26     }
    27     if(pre[x]==low[x]){
    28         int k=0;++scccnt;
    29         while(k!=x){
    30             k=S.top();S.pop();
    31             scc[k]=scccnt;
    32             W[scccnt]+=w[k];
    33             V[scccnt]+=v[k];
    34         }
    35     }
    36 }
    37 void dp(int x){
    38     rep(i,V[x],m+1) d[x][i]=W[x];
    39     rep(i,0,Cnt[x]){
    40         dp(son[x][i]);
    41         for(int h=m;h>=V[x];h--)
    42             rep(t,0,h-V[x]+1) 
    43                 d[x][h]=max(d[x][h],d[x][h-t]+d[son[x][i]][t]);
    44     }
    45 }
    46 int main(){
    47     scanf("%d%d",&n,&m);
    48     rep(i,1,n+1) scanf("%d",v+i);
    49     rep(i,1,n+1) scanf("%d",w+i);
    50     rep(i,1,n+1) scanf("%d",f+i);
    51     rep(i,1,n+1) if(!scc[i]) tarjan(i);
    52     clr(p,0);
    53     rep(i,1,n+1){
    54         if(f[i]&&scc[i]!=scc[f[i]]){
    55             p[scc[i]]=1;
    56             to[scc[i]]=scc[f[i]];
    57             son[scc[f[i]]][Cnt[scc[f[i]]]++]=scc[i];
    58         }
    59     }
    60     root=scccnt+1;
    61     rep(i,1,scccnt+1) if(!p[i]){
    62         son[root][Cnt[root]++]=i;
    63         to[i]=root;
    64     }
    65     dp(root);
    66     cout<<*max_element(d[root],d[root]+m+1)<<"
    ";
    67     return 0;
    68 }
    View Code

    2427: [HAOI2010]软件安装

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 511  Solved: 206
    [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

     

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    谷粒商城学习——P52商品服务-API-三级分类-新增效果
    验证码爆破总结
    利用crawlergo-to-xray实现自动化漏洞被动扫描平台搭建
    数据导入经验总结
    SQL实现2个日期之间的工作日数(MySQL)(转)
    MySQL查询所有表的数据量
    crontab定时配置(转)
    SQLyog还原会话失败
    Nginx以xxx开头的转发
    mysql备份shell脚本
  • 原文地址:https://www.cnblogs.com/chensiang/p/4800704.html
Copyright © 2011-2022 走看看