zoukankan      html  css  js  c++  java
  • BZOJ 2427: [HAOI2010]软件安装( dp )

    软件构成了一些树和一些环, 对于环我们要不不选, 要么选整个环. 跑tarjan缩点后, 新建个root, 往每个入度为0的点(强连通分量) 连边, 然后跑树dp( 01背包 ) 

    ----------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<algorithm>
    #include<vector>
    #include<iostream>
      
    #define rep(i, n) for(int i = 0; i < n; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define Rep(i, n) for(int i = 1; i <= n; ++i)
      
    using namespace std;
     
    const int maxn = 109, maxm = 509;
     
    vector<int> G[maxn];
    stack<int> S;
    int dfn[maxn], low[maxn], scc[maxn], dfs_clock = 0, N = 0, n, m;
    int W[maxn], V[maxn], w_t[maxn], v_t[maxn], d[maxn][maxm];
    bool F[maxn];
     
    void tarjan(int x) {
    dfn[x] = low[x] = ++dfs_clock;
    S.push(x);
    for(vector<int>::iterator it = G[x].begin(); it != G[x].end(); it++)
    if(!dfn[*it]) {
    tarjan(*it);
    low[x] = min(low[x], low[*it]);
    } else if(!scc[*it])
    low[x] = min(low[x], dfn[*it]);
    if(low[x] == dfn[x]) {
    N++;
    int t;
    do {
    t = S.top(); S.pop();
    scc[t] = N;
    w_t[N] += W[t];
    v_t[N] += V[t];
    } while(t != x);
    }
    }
    void TARJAN() {
    clr(w_t, 0), clr(v_t, 0);
    clr(scc, 0), clr(dfn, 0);
    Rep(i, n) if(!dfn[i]) tarjan(i);
    }
     
    struct edge {
    int to;
    edge* next;
    } E[maxn << 2], *pt = E, *head[maxn];
     
    inline void add_edge(int u, int v) {
    F[pt->to = v] = true;
    pt->next = head[u];
    head[u] = pt++;
    }
     
    void build() {
    clr(F, 0), clr(head, 0);
    Rep(i, n) 
       for(vector<int>::iterator it = G[i].begin(); it != G[i].end(); it++)
           if(scc[*it] != scc[i]) add_edge(scc[i], scc[*it]);
    Rep(i, N) if(!F[i])
       add_edge(0, i);
    }
     
    void dp(int x) {
    for(int i = v_t[x]; i <= m; i++) d[x][i] = w_t[x];
    for(edge* e = head[x]; e; e = e->next) {
    dp(e->to);
    for(int h = m; h >= v_t[x]; h--)
       for(int t = 0; t <= h - v_t[x]; t++) 
       d[x][h] = max(d[x][h], d[x][h - t] + d[e->to][t]);
    }
    }
     
    int main() {
    // freopen("test.in", "r", stdin);
    cin >> n >> m;
    Rep(i, n) scanf("%d", V + i);
    Rep(i, n) scanf("%d", W + i);
    Rep(i, n) {
    int v;
    scanf("%d", &v);
    if(v) G[v].push_back(i);
    }
    TARJAN();
    build();
    clr(d, 0), dp(0);
    cout << *max_element(d[0], d[0] + m + 1) << " ";
    return 0;
    }

    ---------------------------------------------------------------------------- 

  • 相关阅读:
    【Swift】WKWebView与JS的交互使用
    【React Native】进阶指南之二(手势响应系统)
    【React Native】进阶指南之一(特定平台、图片加载、动画使用)
    React Native适配IPhoneX系列设备之<SafeAreaView />
    【React Native】react-native之集成支付宝支付、微信支付
    【React Natvie】React-native-swiper的安装和配置【ES6】
    React Native之React Navigation踩坑
    遭遇裁员,如何渡过心理危机?
    Spring 核心技术与产品理念剖析【下】
    Spring 核心技术与产品理念剖析【上】
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4661327.html
Copyright © 2011-2022 走看看