• luogu 2515


    对于软件的依赖可以转化为图上点之间的边的关系
    发现对于一个强联通分量内的软件,一安则全安
    Tarjan缩点
    缩点后,从虚拟节点 0 向所有入度为 0 的点连边
    这样就构成了一棵树
    树形 dp
    $dp[i][j]$ 表示对 $i$ 及其子树话费 $j$ 的价格所得到的收益
    $dp[i][j] = dp[k][l] + dp[i][j - l]$

    #include <bits/stdc++.h>
    
    const int N = 110;
    
    int head[N], cnt;
    struct Node {int u, v, nxt;};
    int Tim, Bel[N], Low[N], Dfn[N], Stack[N], topp;
    int W[N], V[N], Tw[N], Tv[N];
    Node G[N];
    int n, M;
    bool vis[N];
    int Gra;
    
    inline void Add(int u, int v) {G[++ cnt].v = v; G[cnt].nxt = head[u]; head[u] = cnt;}
    
    void Tarjan(int u) {
        Dfn[u] = Low[u] = ++ Tim;
        Stack[++ topp] = u, vis[u] = 1;
        for(int i = head[u]; ~ i; i = G[i].nxt) {
            int v = G[i].v;
            if(!Dfn[v]) {
                Tarjan(v);    
                Low[u] = std:: min(Low[u], Low[v]);
            } else if(vis[v]) Low[u] = std:: min(Low[u], Low[v]);
        }
        if(Low[u] == Dfn[u]) {
            vis[u] = 0, Bel[u] = ++ Gra, Tw[Gra] += W[u], Tv[Gra] += V[u];
            while(Stack[topp] != u) {
                vis[Stack[topp]] = 0, Bel[Stack[topp]] = Gra, Tw[Gra] += W[Stack[topp]], Tv[Gra] += V[Stack[topp]];
                topp --;
            } topp --;
        }
    }
    
    int In[N], head_2[N];
    Node E[N];
    
    inline void Add2(int u, int v) {E[++ cnt].v = v, E[cnt].nxt = head_2[u], head_2[u] = cnt;}
    
    void Re_build() {
        cnt = 0;
        for(int i = 0; i <= Gra; i ++) head_2[i] = -1;
        for(int u = 1; u <= n; u ++)
            for(int i = head[u]; ~ i; i = G[i].nxt) {
                int v = G[i].v;
                if(Bel[u] != Bel[v]) Add2(Bel[u], Bel[v]), In[Bel[v]] = 1;
            }
    }
    
    int f[N][N * 5];
    
    void Dfs(int u) {
        for(int i = head_2[u]; ~ i; i = E[i].nxt) {
            int v = E[i].v;
            Dfs(v);
            for(int j = M - Tw[u]; j >= 0; j --)
                for(int k = 0; k <= j; k ++)
                    f[u][j] = std:: max(f[u][j], f[u][k] + f[v][j - k]);
        }
        for(int j = M; j >= 0; j --) {
            if(j >= Tw[u]) f[u][j] = f[u][j - Tw[u]] + Tv[u];
            else f[u][j] = 0;
        }
    }
    
    #define gc getchar()
    
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    int main() {
        n = read(), M = read();
        for(int i = 1; i <= n; i ++) head[i] = -1;
        for(int i = 1; i <= n; i ++) W[i] = read();
        for(int i = 1; i <= n; i ++) V[i] = read();
        for(int i = 1; i <= n; i ++) {
            int u = read();
            if(u) Add(u, i);
        }
        for(int i = 1; i <= n; i ++) if(!Dfn[i]) Tarjan(i);
        Re_build();
        for(int i = 1; i <= Gra; i ++) if(!In[i]) Add2(0, i);
        Dfs(0);
        std:: cout << f[0][M];
        return 0;
    }
  • 相关阅读:
    URL
    B/S架构
    SQL查询语句
    SQL-Delete语句
    SQL运算符
    SQL结构查询语言
    SQL数据库数据类型详解
    标准文档流
    CSS
    字体样式
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9458410.html
Copyright © 2020-2023  润新知