HAOI2010软件安装
Posted highlights
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HAOI2010软件安装相关的知识,希望对你有一定的参考价值。
题目描述
现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。
但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。
我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。
输入描述:
第1行:N, M (0 ≤ N ≤ 100, 0 ≤ M ≤ 500)
第2行:W1, W2, ... Wi, ..., Wn (0 ≤ Wi ≤ M )
第3行:V1, V2, ..., Vi, ..., Vn (0 ≤ Vi ≤ 1000 )
第4行:D1, D2, ..., Di, ..., Dn (0 ≤ Di ≤ N, Di≠i )
输出描述:
一个整数,代表最大价值。
输入
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; }
以上是关于HAOI2010软件安装的主要内容,如果未能解决你的问题,请参考以下文章