Description
Now we have n software on hand, for a software I, it will occupy WI disk space, its value is VI. We want to choose from some software installed on a disk capacity of M computer, so that the value of these software as large as possible (that is, VI and the largest).
But now there is a problem: there is a dependency between software, that is, software I can work correctly only if software J (including Software J's direct or indirect dependency) is installed (software I relies on software j). Fortunately, one software relies on another software. If a software does not work properly, then it can play a role of 0.
We now know the dependencies between software: Software I relies on software di. Now, please design a solution to install the software as large as possible. A software can only be installed once, if a software is not dependent on the di=0, then as long as the software installed, it will work properly.
Input
Line 1th: N, M (0<=n<=100, 0<=m<=500)
Line 2nd: W1, W2, ... Wi, ..., Wn (0<=wi<=m)
Line 3rd: V1, V2, ..., Vi, ..., Vn (0<=vi<=1000)
Line 4th: D1, D2, ..., Di, ..., Dn (0<=di<=n, Di≠i)
Output
An integer that represents the maximum value.
Sample INPUT3 10
5 5 6
2 3 4
0 1 1 Sample Output5
Tarjan Shrink Point Tree backpack DP
Huang Huge said this kind of problem a lot but I am the first time to do ah ...
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include < algorithm> #include <cmath> #include <queue> #include <deque> #include <set> #include <map > #include <ctime> #define LL long long#define INF 0x7ffffff#define pa pair<int,int> #define Pi 3.1415926535897932384626433832795028841971#define N 110#define M 510using namespace Std;inline ll read () {ll x=0,f=1;ch Ar 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;} inline void Write (LL a) {if (a<0) {printf ("-"); a=-a;} if (a>=10) write (A/10); Putchar (a%10+ ' 0 ');} inline void Writeln (LL a) {write (a);p rintf ("\ n");} struct Edge{int to,next;} E1[2*n],e2[2*n];int head1[n],head2[n];int c[n],w[n],fa[n],belong[n];int c[n],w[n],f[n][m];int dfn[N],low[N];int Zhan[n],top;bool inset[n],mrk[n];int size[n];int n,m,cnt1,cnt2,cnt3,tt,ans;inline void ins1 (int u, int v) {e1[++cnt1].to=v; E1[cnt1].next=head1[u]; Head1[u]=cnt1;} inline void ins2 (int u,int v) {e2[++cnt2].to=v; E2[cnt2].next=head2[u]; Head2[u]=cnt2;} inline void dfs (int x) {low[x]=dfn[x]=++tt; Zhan[++top]=x;inset[x]=1; for (int i=head1[x];i;i=e1[i].next) {if (!dfn[e1[i].to]) {DFS (e1[i].to); Low[x]=min (low[x],low[e1[i].to]); }else if (inset[e1[i].to]) low[x]=min (low[x],dfn[e1[i].to]); } if (Dfn[x]==low[x]) {cnt3++; int p=-1; while (p!=x) {p=zhan[top--]; inset[p]=0; Belong[p]=cnt3; C[CNT3]+=C[P]; W[CNT3]+=W[P]; }}}inline void Tarjan () {for (int i=1;i<=n;i++) if (!dfn[i]) DFS (i);} inline void treedp (int x) {if (mrk[x]) return;mrk[x]=1; for (int i=head2[x];i;i=e2[i].next) if (!mrk[e2[i].to]) {TREEDP (e2[i].to); for (int j=m-c[x];j>=0;j--) for (int k=j; k>=0;k--) F[x][j]=max (F[x][j],f[x][j-k]+f[e2[i].to][k]); } for (int i=m;i>=0;i--) {if (i>=c[x]) f[x][i]=f[x][i-c[x]]+w[x]; else f[x][i]=0; }}int Main () {n=read (); M=read (); for (int i=1;i<=n;i++) c[i]=read (); for (int i=1;i<=n;i++) w[i]=read (); for (int i=1;i<=n;i++) {fa[i]=read (); if (Fa[i]) ins1 (fa[i],i); } Tarjan (); for (int i=1;i<=n;i++) {for (int j=head1[i];j;j=e1[j].next) if (Belong[e1[j].to]!=belong[i]) ins2 (Belong[i], Belong[e1[j].to]); } for (int i=1;i<=cnt3;i++) ins2 (0,i); TREEDP (0); for (int i=0;i<=m;i++) Ans=max (Ans,f[0][i]); printf ("%d\n", ans);}
bzoj2427 [HAOI2010] Software Installation