玄关求调 40pts
查看原帖
玄关求调 40pts
1069671
Rich1楼主2025/7/31 20:18
//[HAOI2010] 软件安装
#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::ios;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using db = double;
using ldb = long double;
using str = std::string;
using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pre(i, a, b) for(int i = (a); i >= (b); --i)
#define mp make_pair
#define ft first
#define sd second
#define ppb pop_back
#define ppf pop_front
#define pb push_back
#define pf push_front
#define eb emplace_back
#define ef emplace_front
#define clr clear
#define ins insert
#define ers erase
#define Mem(a, b) memset(a, b, sizeof a)
#define Copy(a, b) memcpy(a, b, sizeof b)
#define Debug(x) std::cerr << #x << '=' << x << ' '
#define File(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
// #define int ll
// #define double ldb
const int MAXN = 110, MAXM = 510;
int n, m;
int ww[MAXN], vv[MAXN];
template<typename Tp, const int pt, const int ed>
class ChainForwardStar {
  public:
    struct Edge {
        int v, nx;
        Tp w;
    } e[ed];
    int h[pt], idx;
    ChainForwardStar() { Clear(); }
    void Clear() { Mem(h, -1), idx = 0; }
    void AddEdge(int u, int v, Tp w = 1) {
        e[idx] = {v, h[u], w};
        h[u] = idx++;
    }
    template<typename Func>
    void ForEach(int u, Func func) const {
        for(int i = h[u]; i != -1; i = e[i].nx)
            func(e[i].v, e[i].w);
    }
};
ChainForwardStar<int, MAXN, MAXN << 1> C, C1;
int dfn[MAXN], low[MAXN], timestamp;
std::stack<int> stk;
bool instk[MAXN];
int scc[MAXN], cnt, w[MAXN], v[MAXN];
void Tarjan(int u) {
    dfn[u] = low[u] = ++timestamp;
    stk.push(u);
    instk[u] = true;
    C.ForEach(u, [&](int v, int w) {
        if(dfn[v] == 0) {
            Tarjan(v);
            low[u] = std::min(low[u], low[v]);
        } 
        else if(instk[v])
            low[u] = std::min(low[u], dfn[v]);
    });
    if(dfn[u] == low[u]) {
        ++cnt;
        int x;
        do {
            x = stk.top(); stk.pop();
            scc[x] = cnt;
            w[cnt] += ww[x];
            v[cnt] += vv[x];
        } while(x != u);
    }
}
int in[MAXN];
int dp[MAXN][MAXM];
void Dfs(int u) {
    rep(i, w[u], m) dp[u][i] = v[u];
    C1.ForEach(u, [&](int v, int www) {
        Dfs(v);
        pre(i, m - w[u], 0)
            rep(j, 0, i)
                dp[u][i + w[u]] =  std::max(dp[u][i + w[u]],  dp[v][j] + dp[u][i + w[u] - j]);
    });
}
int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n >> m;
    rep(i, 1, n) cin >> ww[i];
    rep(i, 1, n) cin >> vv[i];
    rep(i, 1, n) {
        int d; cin >> d;
        if(d == 0) continue;
        C.AddEdge(d, i);
    }
    rep(i, 1, n) if(dfn[i] == 0) Tarjan(i);
    rep(u, 1, n) {
        C.ForEach(u, [&](int v, int w) {
            if(scc[u] == scc[v]) return;
            C1.AddEdge(scc[u], scc[v]);
            ++in[scc[v]];
        });
    }
    rep(i, 1, cnt) if(in[i] == 0) C1.AddEdge(0, i);
    Mem(dp, -0x3f);
    Dfs(0);
    cout << dp[0][m];
    return 0;
}
2025/7/31 20:18
加载中...