• bzoj 2427


    tarjan缩点后即为根,然后就是简单的树型DP

    然而DP花了我好长时间QAQ得找个时间练DP才行

     1 #include<bits/stdc++.h>
     2 #define inc(i,l,r) for(int i=l;i<=r;i++)
     3 #define dec(i,l,r) for(int i=l;i>=r;i--)
     4 #define link(x) for(edge *j=h[x];j;j=j->next)
     5 #define mem(a) memset(a,0,sizeof(a))
     6 #define inf 1e9
     7 #define ll long long
     8 #define succ(x) (1<<x)
     9 #define NM 500+5
    10 using namespace std;
    11 int read(){
    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*10+ch-'0',ch=getchar();
    15     return x*f;
    16 }
    17 struct edge{
    18     int t,v;
    19     edge *next;
    20 }e[2*NM],*h[NM],*o=e;
    21 void add(int x,int y){
    22     o->t=y;o->next=h[x];h[x]=o;o++;
    23 }
    24 int n,m,a[NM],b[NM],_d[NM][NM],d[NM],suc[NM],low[NM],_x,_y,_t,tot,cnt,ans;
    25 bool v[NM];
    26 stack<int >s;
    27 void dfs(int x){
    28     d[x]=low[x]=++tot;s.push(x);
    29     link(x)
    30     if(!d[j->t]){
    31         dfs(j->t);
    32         low[x]=min(low[x],low[j->t]);
    33     }else if(!suc[j->t])
    34     low[x]=min(low[x],low[j->t]);
    35     if(d[x]==low[x]){
    36         int t;cnt++;
    37         do{
    38             t=s.top();s.pop();
    39             suc[t]=cnt;
    40         }while(x!=t);
    41     }
    42 }
    43 void dp(int x){
    44     inc(i,a[x],m)_d[x][i]=b[x];
    45     link(x){
    46         dp(j->t);
    47         dec(k,m,a[x])
    48         inc(i,a[j->t],k-a[x])
    49         if(k>=i)
    50         _d[x][k]=max(_d[x][k],_d[j->t][i]+_d[x][k-i]);
    51     }
    52 }
    53 int main(){
    54 //    freopen("data.in","r",stdin);
    55     n=read();m=read();
    56     inc(i,1,n)a[i]=read();
    57     inc(i,1,n)b[i]=read();
    58     inc(i,1,n)
    59     if(_x=read())
    60     add(_x,i),v[i]++;
    61     inc(i,1,n)
    62     if(!v[i])dfs(i);
    63     inc(i,1,n)
    64     if(!d[i])dfs(i);
    65     inc(i,1,cnt){
    66         _x=_y=_t=0;
    67         inc(j,1,n)
    68         if(suc[j]==i)_x+=a[j],_y+=b[j],_t++;
    69         if(_t==1){
    70             inc(j,1,n)
    71             if(suc[j]==i&&!v[j])
    72             add(0,j);
    73         }else{
    74             a[++n]=_x;b[n]=_y;
    75             add(0,n);
    76             inc(k,1,n)
    77             if(suc[k]==i)
    78             link(k)
    79             if(suc[j->t]!=i)add(n,j->t);
    80         }
    81     }
    82     dp(0);
    83     inc(i,1,m)ans=max(ans,_d[0][i]);
    84     printf("%d
    ",ans);
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    机器学习数学符号解释
    JVM Guide
    Mysql优化
    JAVA必会算法--冒泡排序
    HashMap-JDK源码阅读
    vue 下载文件
    CommonMethod
    log4net 写日志
    WebAPI 封装返回值
    二, .NET Core 微服务学习 ——集中式代理-Nginx
  • 原文地址:https://www.cnblogs.com/onlyRP/p/5100343.html
Copyright © 2020-2023  润新知