一开始读错题导致各种不会做,无奈
其实是一道水题,缩点反向建图树形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.
View Code

 

posted on 2014-12-11 21:42  acphile  阅读(118)  评论(0编辑  收藏  举报