• [树形DP][背包]luogu P2515 软件安装


    https://www.luogu.org/problemnew/show/P2515

    分析

    沙雕题*2

    这题就是随便做个树形背包,Tarjan缩点把价值和体积加起来而已

    注意必须保留当前节点的价值和体积

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    const int N=110;
    const int M=510;
    struct Graph {
        int u,v,nx;
    }g[N*N];
    int cnt,list[N],deg[N];
    int low[N],dfn[N],tme;
    int stk[N],top;
    bool instk[N];
    int w[N],v[N],idw[N],idv[N],id[N],idcnt;
    int n,m,rt;
    int f[N][M];
    
    void Add(int u,int v) {
        g[++cnt]=(Graph){u,v,list[u]};list[u]=cnt;
    }
    
    void Tarjan(int u) {
        dfn[u]=low[u]=++tme;
        stk[++top]=u;instk[u]=1;
        for (int i=list[u];i;i=g[i].nx)
            if (!dfn[g[i].v]) {
                Tarjan(g[i].v);
                low[u]=min(low[u],low[g[i].v]);
            }
            else if (instk[g[i].v]) low[u]=min(low[u],dfn[g[i].v]);
        if (low[u]==dfn[u])    {
            idcnt++;
            do {
                id[stk[top]]=idcnt;idw[idcnt]+=w[stk[top]];idv[idcnt]+=v[stk[top]];
                instk[stk[top]]=0;
            }
            while (stk[top--]!=u);
        }
    }
    
    void DFS(int u) {
        if (idw[u]<=m) f[u][idw[u]]=idv[u];
        for (int i=idw[u]+1;i<=m;i++) f[u][i]=f[u][i-1];
        for (int i=list[u];i;i=g[i].nx) {
            DFS(g[i].v);
            for (int j=m;j>=idw[u];j--)
                for (int k=idw[g[i].v];k<=j-idw[u];k++)
                    f[u][j]=max(f[u][j],f[u][j-k]+f[g[i].v][k]);
        }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&w[i]);
        for (int i=1;i<=n;i++) scanf("%d",&v[i]);
        for (int i=1,f;i<=n;i++) {
            scanf("%d",&f);
            if (f) Add(f,i);
        }
        for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i);
        memset(list,0,sizeof list);cnt=0;
        for (int i=1;i<=m;i++) if (id[g[i].u]!=id[g[i].v]) deg[id[g[i].v]]++,Add(id[g[i].u],id[g[i].v]);
        for (int i=1;i<=idcnt;i++) if (!deg[i]) Add(0,i);
        DFS(0);
        printf("%d",f[0][m]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    hihocoder1238 Total Highway Distance(树形dp)
    POJ2104 K-th Number(主席树)
    ansible安装使用入门
    TIDB资料收集
    elasticssearch+kibanna入门(撰写中)
    fabric-sdk-java在IDEA中的使用
    安装hyperledger fabric V1.0.1
    fabric读书笔记
    fabric默认样例的分析
    在eclipse中安装go编辑器阅读fabric代码
  • 原文地址:https://www.cnblogs.com/mastervan/p/11155106.html
Copyright © 2020-2023  润新知