一开始读错题导致各种不会做,无奈
其实是一道水题,缩点反向建图树形dp即可
1 type link=^point; 2 point=record 3 po:longint; 4 next:link; 5 end; 6 7 var dfn,low,st,w,be,v,c:array[0..2010] of longint; 8 e:array[0..1010] of link; 9 fa,vis,f:array[0..1010] of boolean; 10 dp:array[0..210,0..2010,0..2] of longint; 11 y,s,h,t,ans,i,j,n,m,x:longint; 12 ch:boolean; 13 14 function min(a,b:longint):longint; 15 begin 16 if a>b then exit(b) else exit(a); 17 end; 18 19 function max(a,b:longint):longint; 20 begin 21 if a>b then exit(a) else exit(b); 22 end; 23 24 procedure add(x,y:longint); 25 var p:link; 26 begin 27 new(p); 28 p^.po:=y; 29 p^.next:=e[x]; 30 e[x]:=p; 31 end; 32 33 procedure tarjan(x:longint); 34 var y,r:longint; 35 p:link; 36 begin 37 inc(h); 38 dfn[x]:=h; 39 low[x]:=h; 40 vis[x]:=true; 41 f[x]:=true; 42 inc(t); 43 st[t]:=x; 44 p:=e[x]; 45 while p<>nil do 46 begin 47 y:=p^.po; 48 if not vis[y] then 49 begin 50 tarjan(y); 51 low[x]:=min(low[x],low[y]); 52 end 53 else if f[y] then low[x]:=min(low[x],low[y]); 54 p:=p^.next; 55 end; 56 if dfn[x]=low[x] then 57 begin 58 while st[t+1]<>x do 59 begin 60 r:=st[t]; 61 be[r]:=x; 62 f[r]:=false; 63 dec(t); 64 end; 65 end; 66 end; 67 68 procedure treedp(x:longint); 69 var y,i,j,k:longint; 70 p:link; 71 begin 72 p:=e[x]; 73 dp[x,w[x],0]:=v[x]; 74 k:=0; 75 while p<>nil do 76 begin 77 y:=p^.po; 78 treedp(y); 79 k:=1-k; 80 for i:=0 to m do 81 dp[x,i,k]:=dp[x,i,1-k]; 82 for i:=0 to m-w[x] do 83 if dp[y,i,1]>0 then 84 begin 85 for j:=w[x] to m-i do 86 dp[x,j+i,k]:=max(dp[x,j+i,k],dp[x,j,1-k]+dp[y,i,1]); 87 end; 88 p:=p^.next; 89 end; 90 if k=0 then 91 for i:=0 to m do 92 dp[x,i,1]:=dp[x,i,0]; 93 end; 94 95 begin 96 readln(n,m); 97 for i:=1 to n do 98 read(w[i]); 99 for i:=1 to n do 100 read(v[i]); 101 for i:=1 to n do 102 begin 103 read(c[i]); 104 if c[i]<>0 then add(i,c[i]); 105 end; 106 for i:=1 to n do 107 if not vis[i] then 108 begin 109 h:=0; 110 t:=0; 111 tarjan(i); 112 end; 113 114 for i:=1 to n do 115 begin 116 if be[i]<>i then 117 begin 118 inc(w[be[i]],w[i]); 119 inc(v[be[i]],v[i]); 120 end; 121 e[i]:=nil; 122 end; 123 for i:=1 to n do 124 if be[i]=i then 125 begin 126 if (be[c[i]]=i) or (c[i]=0) then add(0,i) 127 else add(be[c[i]],i); 128 end; 129 ans:=0; 130 v[0]:=0; 131 w[0]:=0; 132 treedp(0); 133 for i:=1 to m do 134 ans:=max(ans,dp[0,i,1]); 135 writeln(ans); 136 end.