把环缩成一个点...
建立超级根0....
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();}
while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
return x*f;
}
#define MAXN 110
#define MAXM 510
struct EdgeNode{int next,to;}edge[MAXN<<1],road[MAXN<<1];
int head[MAXN],cnt=1,first[MAXN],tot=1;
inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
inline void InsertEdge(int u,int v) {if (!u) return; AddEdge(u,v);}
int w[MAXN],v[MAXN],V[MAXN],W[MAXN],N,M;
int dfn[MAXN],low[MAXN],st[MAXN],top,visit[MAXN],belong[MAXN],size[MAXN],dfsn,scc;
inline void Tarjan(int x)
{
dfn[x]=low[x]=++dfsn; visit[x]=1; st[++top]=x;
for (int i=head[x]; i; i=edge[i].next)
if (!dfn[edge[i].to]) Tarjan(edge[i].to),low[x]=min(low[x],low[edge[i].to]);
else if (visit[edge[i].to]) low[x]=min(dfn[edge[i].to],low[x]);
if (dfn[x]==low[x])
{
int stp=0;
scc++;
while (x!=stp) stp=st[top--],size[scc]++,W[scc]+=w[stp],V[scc]+=v[stp],belong[stp]=scc,visit[stp]=0;
}
}
inline void AddRoad(int u,int v) {tot++; road[tot].next=first[u]; first[u]=tot; road[tot].to=v;}
inline void InsertRoad(int u,int v) {AddRoad(u,v); AddRoad(v,u);}
bool flag[MAXN];
inline void Rebuild()
{
for (int i=1; i<=N; i++)
for (int j=head[i]; j; j=edge[j].next)
if (belong[i]!=belong[edge[j].to])
InsertRoad(belong[i],belong[edge[j].to]),flag[belong[edge[j].to]]=1;
for (int i=1; i<=scc; i++) if (!flag[i]) InsertRoad(0,i);
}
int f[MAXN][MAXM],g[MAXN][MAXM];
void DP(int x,int last)
{
for (int i=first[x]; i; i=road[i].next)
if (road[i].to!=last)
{
DP(road[i].to,x);
for (int j=M-W[x]; j>=0; j--)
for (int k=0; k<j; k++)
g[x][j]=max(g[x][j],g[x][k]+f[road[i].to][j-k]);
}
for (int i=0; i<=M-W[x]; i++) f[x][i+W[x]]=g[x][i]+V[x];
}
int main()
{
N=read(),M=read();
for (int i=1; i<=N; i++) w[i]=read();
for (int i=1; i<=N; i++) v[i]=read();
for (int f,i=1; i<=N; i++) f=read(),InsertEdge(f,i);
for (int i=1; i<=N; i++) if (!dfn[i]) Tarjan(i);
Rebuild();
DP(0,0);
printf("%d\n",f[0][M]);
return 0;
}