• [BZOJ1791][IOI2008]Island岛屿(环套树DP)


    同NOI2013快餐店(NOI出原题?),下面代码由于BZOJ栈空间过小会RE。

    大致是对每个连通块找到环,在所有内向树做一遍DP,再在环上做两遍前缀和优化的DP。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     7 typedef long long ll;
     8 using namespace std;
     9 
    10 const int N=1000010;
    11 ll ans,res,f[N],v1[N],v2[N],u1[N],u2[N];
    12 int dfn[N],fa[N],pre[N],h[N],a[N],b[N];
    13 int n,x,w,cnt,tim,tot,to[N<<1],val[N<<1],nxt[N<<1],d[N];
    14 void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }
    15 
    16 void dfs(int x){
    17     dfn[x]=++tim;
    18     For(i,x) if ((k=to[i])!=fa[x]){
    19         if (!dfn[k]) fa[k]=x,pre[k]=val[i],dfs(k);
    20         else if (dfn[k]>dfn[x]){
    21             for (int t=k; t!=x; t=fa[t]) a[++tot]=t,d[t]=1,b[tot]=pre[t];
    22             a[++tot]=x; d[x]=1; b[tot]=val[i];
    23         }
    24     }
    25 }
    26 
    27 void Dfs(int x,int fa){
    28     For(i,x) if ((k=to[i])!=fa && !d[k])
    29         Dfs(k,x),ans=max(ans,f[x]+f[k]+val[i]),f[x]=max(f[x],f[k]+val[i]);
    30 }
    31 
    32 void DP(int x){
    33     tot=0; ans=0; dfs(x); ll sm=0,mx=0;
    34     rep(i,1,tot) Dfs(a[i],0);
    35     rep(i,1,tot) d[a[i]]=0;
    36     rep(i,0,tot+1) u1[i]=u2[i]=v1[i]=v2[i]=0;
    37     rep(i,1,tot){
    38         sm+=b[i-1]; u1[i]=max(u1[i-1],f[a[i]]+sm);
    39         v1[i]=max(v1[i-1],f[a[i]]+sm+mx); mx=max(mx,f[a[i]]-sm);
    40         ans=max(ans,v1[i]);
    41     }
    42     int tmp=b[tot]; sm=mx=b[tot]=0;
    43     for (int i=tot; i; i--){
    44         sm+=b[i]; u2[i]=max(u2[i+1],f[a[i]]+sm);
    45         v2[i]=max(v2[i+1],f[a[i]]+sm+mx); mx=max(mx,f[a[i]]-sm);
    46         ans=max(ans,v2[i]);
    47     }
    48     rep(i,1,tot-1) ans=max(ans,u1[i]+u2[i+1]+tmp);
    49     res+=ans;
    50 }
    51 
    52 int main(){
    53     freopen("bzoj1791.in","r",stdin);
    54     freopen("bzoj1791.out","w",stdout);
    55     scanf("%d",&n);
    56     rep(i,1,n) scanf("%d%d",&x,&w),add(x,i,w),add(i,x,w);
    57     rep(i,1,n) if (!dfn[i]) DP(i);
    58     printf("%lld
    ",res);
    59     return 0;
    60 }
  • 相关阅读:
    软件设计分层
    技术填补
    崩溃预防
    架构前期准备
    系统重构
    如何保证架构的质量(稳定性和健壮性)
    你知道有哪些架构师吗
    12 koarouter
    11 Koa起步
    Hadoop源码分析hdfs(1)启动脚本分析
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9932161.html
Copyright © 2020-2023  润新知