标签:-- 计算机 i++ 描述 for 磁盘容量 bsp title names
一个整数,代表最大价值。
3 10 5 5 6 2 3 4 0 1 1
5
//缩点是为了处理图中的环,缩点之后就是一个简单的树型背包dp了 #include<bits/stdc++.h> using namespace std; const int N = 1e3 + 7; int dp[N][N], W[N], V[N], w[N], v[N]; int head[N], ver[N], nex[N], tot, n, m; int in[N], dfn[N], low[N], st[N], vis[N], c[N], cnt, top, num; vector<int> scc[N]; void add(int x, int y) { ver[++tot] = y; nex[tot] = head[x]; head[x] = tot; } void tarjan(int x) { low[x] = dfn[x] = ++num; st[top++] = x; vis[x] = 1; for (int i = head[x]; i; i = nex[i]) { int y = ver[i]; if (!dfn[y]) { tarjan(y); low[x] = min(low[x], low[y]); } else if (vis[y]) low[x] = min(low[x], dfn[y]); } if (low[x] == dfn[x]) { int y; ++cnt; do { y = st[--top]; vis[y] = 0; c[y] = cnt; v[cnt] += V[y]; w[cnt] += W[y]; } while (x != y); } } void Dp(int x) { for (int i = w[x]; i <= m; i++) dp[x][i] = v[x]; for (int y: scc[x]) { Dp(y); for (int i = m - w[x]; i >= 0; i--) { for (int j = 0; j <= i; j++) { dp[x][i + w[x]] = max(dp[x][i + w[x]], dp[x][i + w[x] - j] + dp[y][j]); } } } } int main() { int x; cin >> n >> m; for (int i = 1; i <= n; i++) cin >> W[i]; for (int i = 1; i <= n; i++) cin >> V[i]; for (int i = 1; i <= n; i++) { cin >> x; if (x) add(x, i); } for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i); for (x = 1; x <= n; x++) { for (int j = head[x]; j; j = nex[j]) { int y = ver[j]; if (c[x] != c[y]) scc[c[x]].push_back(c[y]), in[c[y]]++; } } for (int i = 1; i <= cnt; i++) { if (!in[i]) scc[0].push_back(i); } Dp(0); cout << dp[0][m] << endl; return 0; }
标签:-- 计算机 i++ 描述 for 磁盘容量 bsp title names
原文地址:https://www.cnblogs.com/HighLights/p/13323920.html