1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <cstring>
5 #include <cmath>
6 #include <algorithm>
7 #define min(a, b) ((a) < (b) ? (a) : (b))
8 #define max(a, b) ((a) > (b) ? (a) : (b))
9
10 inline void read(int &x)
11 {
12 x = 0;char ch = getchar(), c = ch;
13 while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
14 while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
15 if(c == ‘-‘)x = -x;
16 }
17
18 const int INF = 0x3f3f3f3f;
19 const int MAXN = 100 + 10;
20 const int MAXM = 500 + 10;
21
22 int n,m,cost[MAXN],value[MAXN];
23
24 struct Edge
25 {
26 int u,v,next;
27 Edge(int _u, int _v, int _next){u = _u;v = _v;next = _next;}
28 Edge(){}
29 }edge[MAXN << 1];
30 int head[MAXN], cnt;
31
32 inline void insert(int a, int b)
33 {
34 edge[++cnt] = Edge(a, b, head[a]);
35 head[a] = cnt;
36 }
37
38 int b[MAXN],bb[MAXN],low[MAXN],dfn[MAXN],belong[MAXN],group,tot,stack[MAXN],top;
39
40 void tarjan_dfs(int u)
41 {
42 dfn[u] = low[u] = ++tot;
43 b[u] = bb[u] = 1;
44 stack[++top] = u;
45 for(register int pos = head[u];pos;pos = edge[pos].next)
46 {
47 int v = edge[pos].v;
48 if(!b[v])
49 {
50 tarjan_dfs(v);
51 low[u] = min(low[u], low[v]);
52 }
53 else if(bb[v] && low[u] > dfn[v])
54 low[u] = dfn[v];
55 }
56 if(low[u] == dfn[u])
57 {
58 ++ group;
59 int now = 0;
60 while(now != u)
61 {
62 now = stack[top --];
63 belong[now] = group;
64 bb[now] = false;
65 }
66 }
67 }
68
69 int cost2[MAXN],value2[MAXN],l[MAXN],r[MAXN],fa2[MAXN];
70
71 void tarjan()
72 {
73 for(register int i = 1;i <= n;++ i) if(!b[i]) tarjan_dfs(i);
74 for(register int u = 1;u <= n;++ u)
75 {
76 for(register int pos = head[u];pos;pos = edge[pos].next)
77 {
78 int v = edge[pos].v;
79 if(belong[v] != belong[u])
80 fa2[belong[v]] = belong[u];
81 }
82 cost2[belong[u]] += cost[u];
83 value2[belong[u]] += value[u];
84 }
85 for(register int i = 1;i <= group;++ i)
86 if(fa2[i])r[i] = l[fa2[i]], l[fa2[i]] = i;
87 }
88
89 int dp[MAXN][MAXM],dpb[MAXN];
90
91 void DP(int u)
92 {
93 if(!u || dpb[u])return;
94 dpb[u] = 1;
95 /*
96 dp[i][j]表示i和i右边的兄弟消耗磁盘空间j的最大价值
97 dp[i][j] = max{
98 选 f[l[i]][a] + f[r[i]][j - a - cost[i]] + value[i]
99
100 不选 f[r[i]][j]
101 }
102 */
103 DP(l[u]), DP(r[u]);
104 for(register int j = 0;j <= m;++ j)
105 {
106 for(register int a = 0;a <= m;++ a)
107 {
108 //dp[u][j] = max(dp[u][j], dp[u][j - 1]);
109 if(j - a - cost2[u] >= 0) dp[u][j] = max(dp[u][j], dp[l[u]][a] + dp[r[u]][j - a - cost2[u]] + value2[u]);
110 dp[u][j] = max(dp[u][j], dp[r[u]][j]);
111 }
112 }
113 }
114
115 int main()
116 {
117 read(n), read(m);
118 register int tmp;
119 for(register int i = 1;i <= n;++ i) read(cost[i]);
120 for(register int i = 1;i <= n;++ i) read(value[i]);
121 for(register int i = 1;i <= n;++ i)
122 {
123 read(tmp);
124 if(tmp)insert(tmp, i);
125 }
126 tarjan();
127 int root = 1;
128 while(!l[root] && root <= group)++ root;
129 if(root <= group)
130 {
131 while(fa2[root])root = fa2[root];
132 l[group + 1] = root;
133 fa2[root] = group + 1,
134 root = group + 1;
135 ++ group;
136 }
137 else
138 root = group + 1;
139 for(register int i = 1;i <= group;++ i)
140 if(!fa2[i] && i != root) r[i] = l[root], l[root] = i, fa2[i] = root;
141 cost2[root] = value2[root] = 0;
142 DP(root);
143 printf("%d", dp[root][m]);
144 return 0;
145 }