【HAOI2010】软件安装
题面
题解
缩点之后一个裸的树型背包
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
using std::min; using std::max;
inline int read()
{
int data = 0, w = 1;
char ch = getchar();
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}
const int maxn(1010);
struct edge { int next, to; } e[maxn << 1];
int n, m, e_num, top, col, cnt, W[maxn], w[maxn], V[maxn], v[maxn], f[maxn][maxn], head[maxn];
inline void add_edge(int from, int to)
{
e[++e_num] = (edge) {head[from], to};
head[from] = e_num;
}
int dfn[maxn], low[maxn], stk[maxn], belong[maxn], d[maxn], ind[maxn];
void Tarjan(int x)
{
dfn[x] = low[x] = ++cnt;
stk[++top] = x;
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to;
if(!dfn[to]) Tarjan(to), low[x] = min(low[x], low[to]);
else if(!belong[to]) low[x] = min(low[x], dfn[to]);
}
if(dfn[x] == low[x])
{
belong[x] = ++col; V[col] = v[x]; W[col] = w[x];
while(stk[top] != x) belong[stk[top]] = col, V[col] += v[stk[top]], W[col] += w[stk[top--]];
--top;
}
}
void dfs(int x)
{
for(RG int i = W[x]; i <= m; i++) f[x][i] = V[x];
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to; dfs(to);
for(RG int j = m - W[x]; j >= 0; j--)
for(RG int k = 0; k <= j; k++)
f[x][j + W[x]] = max(f[x][j + W[x]], f[to][k] + f[x][j + W[x] - k]);
}
}
int main()
{
scanf("%d%d", &n, &m);
for(RG int i = 1; i <= n; i++) scanf("%d", w + i);
for(RG int i = 1; i <= n; i++) scanf("%d", v + i);
for(RG int i = 1; i <= n; i++) { scanf("%d", d + i); if(d[i]) add_edge(d[i], i); }
for(RG int i = 1; i <= n; i++) if(!dfn[i]) Tarjan(i);
memset(head, 0, sizeof(head)); memset(e, 0, sizeof(e)); e_num = 0;
for(RG int i = 1; i <= n; i++) if(belong[d[i]] != belong[i]) add_edge(belong[d[i]], belong[i]), ++ind[belong[i]];
for(RG int i = 1; i <= col; i++) if(ind[i] == 0) add_edge(0, i);
dfs(0); printf("%d\n", f[0][m]);
return 0;
}