Backpack is a simple DP, put it in the tree is not simple.
Tree backpack primary practices:
Set f [i] [j] is the i-node is the root, i is a volume of maximum benefit. In fact, the original F [u] [i] [j] u is expressed in root, select subtree i, j is a volume of maximum benefit, but by the volume of that dimension reverse cycle (the same as a backpack 01) may be on the space optimization of O (n ^ 2), but still large time as O (n ^ 3).
f [i] [j] = max (f [i] [j], f [i] [jk] + f [v] [k]) (reverse cycle j, k from 0 to j.)
The answer is F [root] [backpack volume]
So there Optimization:
Set F [i] [j] represents the sequence from i to dfs tot, j is the value of the maximum volume.
First dfs again, each of them calculating siz [] subtree, and a mapping of each of the original number sequence dfs, (id [++ num] = x).
f [i] [j] = max (f [i + siz [i]] [j], f [i + 1] [jw [i]] + val [i]) (i reverse circulation)
The answer is f [1] [volume] backpack
There are other optimization, but I will not. . .
Here is the code:
Examples luogu P2515 [HAOI2010] software installation
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define RE register 4 using namespace std; 5 const int maxn=2200; 6 inline int R(){ 7 RE char b=getchar();int x=0,t=1; 8 while(b<'0'||b>'9'){if(b=='-') t=-1;b=getchar();} 9 while(b>='0'&&b<='9') {x=(x<<3)+(x<<1)+b-'0';b=getchar();} 10 return x*t; 11 } 12 struct Edge{ 13 int nxt,to; 14 }ed[maxn]; 15 int head[maxn],ecnt; 16 void addedge(int f,int to){ 17 ed[++ecnt].to=to; 18 ed[ecnt].nxt=head[f]; 19 head[f]=ecnt; 20 } 21 int n,m; 22 int w[maxn],v[maxn],d[maxn]; 23 int ww[maxn],vv[maxn],rd[maxn]; 24 int siz[maxn]; 25 int f[maxn][maxn]; 26 void dfs(int x){// 划重点 27 for(int i=ww[x];i<=m;i++) f[x][i]=vv[x]; 28 // f[x][ww[x]]=vv[x]; 29 for(int i=head[x];i;i=ed[i].nxt){ 30 int v=ed[i].to; 31 dfs(v); 32 for(int j=m-ww[x];j>=0;j--) for(int k=0;k<=j;k++){ 33 f[x][j+ww[x]]=max(f[x][j+ww[x]],f[x][j+ww[x]-k]+f[v][k]); 34 } 35 } 36 } 37 int dfn[maxn],low[maxn],num; 38 bool vis[maxn]; 39 int sta[maxn],tp; 40 int scc_num,scc[maxn]; 41 void tarjan(int x){ 42 sta[++tp]=x; 43 vis[x]=1; 44 dfn[x]=low[x]=++num; 45 for(int i=head[x];i;i=ed[i].nxt){ 46 int v=ed[i].to; 47 if(!dfn[v]){ 48 tarjan(v); 49 low[x]=min(low[x],low[v]); 50 } 51 else if(vis[v]) low[x]=min(low[x],dfn[v]); 52 } 53 if(low[x]==dfn[x]){ 54 scc_num++; 55 int tmp; 56 do{ 57 tmp=sta[tp--]; 58 vis[tmp]=0; 59 scc[tmp]=scc_num; 60 ww[scc_num]+=w[tmp]; 61 vv[scc_num]+=v[tmp]; 62 }while(tmp!=x); 63 } 64 } 65 int main(){ 66 n=R(),m=R(); 67 for(int i=1;i<=n;i++) w[i]=R(); 68 for(int i=1;i<=n;i++) v[i]=R(); 69 for(int i=1;i<=n;i++){ 70 d[i]=R(); 71 if(d[i]) addedge(d[i],i); 72 } 73 for(int i=1;i<=n;i++){ 74 if(!dfn[i]) tarjan(i); 75 } 76 memset(head,0,sizeof head); 77 memset(ed,0,sizeof ed);ecnt=0; 78 for(int i=1;i<=n;i++){ 79 int f=d[i],to=i; 80 if(scc[f]!=scc[to]&&f) addedge(scc[f],scc[to]),rd[scc[to]]++; 81 } 82 for(int i=1;i<=scc_num;i++) 83 if(!rd[i]) addedge(scc_num+1,i);//Sure source condensing point plus super, and super or not the ring is attached on top of the source 84 DFS (+ scc_num . 1 ); 85 the printf ( " % D \ n- " , F [scc_num + . 1 ] [m]); 86 return 0 ; 87 }
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define RE register 4 using namespace std; 5 const int maxn=2200; 6 inline int R(){ 7 RE char b=getchar();int x=0,t=1; 8 while(b<'0'||b>'9'){if(b=='-') t=-1;b=getchar();} 9 while(b>='0'&&b<='9') {x=(x<<3)+(x<<1)+b-'0';b=getchar();} 10 return x*t; 11 } 12 struct Edge{ 13 int nxt,to; 14 }ed[maxn]; 15 int head[maxn],ecnt; 16 void addedge(int f,int to){ 17 ed[++ecnt].to=to; 18 ed[ecnt].nxt=head[f]; 19 head[f]=ecnt; 20 } 21 int n,m; 22 int w[maxn],v[maxn],d[maxn]; 23 int ww[maxn],vv[maxn],rd[maxn]; 24 int siz[maxn]; 25 int f[maxn][maxn]; 26 //void dfs(int x){ 27 // for(int i=ww[x];i<=m;i++) f[x][i]=vv[x]; 28 //// f[x][ww[x]]=vv[x]; 29 // for(int i=head[x];i;i=ed[i].nxt){ 30 // int v=ed[i].to; 31 // dfs(v); 32 // for(int j=m-ww[x];j>=0;j--) for(int k=0;k<=j;k++){ 33 // f[x][j+ww[x]]=max(f[x][j+ww[x]],f[x][j+ww[x]-k]+f[v][k]); 34 // } 35 // } 36 //} 37 int id[maxn],num; 38 void dfs(int x){ 39 id[++num]=x;//划重点 40 siz[x]=1; 41 for(int i=head[x];i;i=ed[i].nxt){ 42 int v=ed[i].to; 43 dfs(v); 44 siz[x]+=siz[v]; 45 } 46 } 47 int dfn[maxn],low[maxn]; 48 bool vis[maxn]; 49 int sta[maxn],tp; 50 int scc_num,scc[maxn]; 51 void tarjan(int x){ 52 sta[++tp]=x; 53 vis[x]=1; 54 dfn[x]=low[x]=++num; 55 for(int i=head[x];i;i=ed[i].nxt){ 56 int v=ed[i].to; 57 if(!dfn[v]){ 58 tarjan(v); 59 low[x]=min(low[x],low[v]); 60 } 61 else if(vis[v]) low[x]=min(low[x],dfn[v]); 62 } 63 if(low[x]==dfn[x]){ 64 scc_num++; 65 int tmp; 66 do{ 67 tmp=sta[tp--]; 68 vis[tmp]=0; 69 scc[tmp]=scc_num; 70 ww[scc_num]+=w[tmp]; 71 vv[scc_num]+=v[tmp]; 72 }while(tmp!=x); 73 } 74 } 75 int main(){ 76 n=R(),m=R(); 77 for(int i=1;i<=n;i++) w[i]=R(); 78 for(int i=1;i<=n;i++) v[i]=R(); 79 for(int i=1;i<=n;i++){ 80 d[i]=R(); 81 if(d[i]) addedge(d[i],i); 82 } 83 for(int i=1;i<=n;i++){ 84 if(!dfn[i]) tarjan(i); 85 } 86 memset(head,0,sizeof head); 87 memset(ed,0,sizeof ed);ecnt=0; 88 for(int i=1;i<=n;i++) { 89 int F = D [I], to = I; 90 IF ! (SCC [F] = SCC [to] && F) addedge (SCC [F], SCC [to]), RD [SCC [to]] ++ ; 91 is } 92 for ( int I = . 1 ; I <= scc_num; I ++ ) 93 IF addedge (scc_num + (RD [I]!) . 1 , I); // be sure plus super condensing point source, otherwise rings are not connected and the top of the super source 94 Memset (DFN, 0 , the sizeof DFN); NUM = 0 ; 95 DFS (+ scc_num . 1 ); 96 for ( int I = NUM; I; I -) { / /Draw key 97 for ( int J = 0 ; J <= m; J ++ ) 98 IF (J-WW [ID [I]]> = 0 ) F [I] [J] = max (F [I + SIZ [ID [I]]] [J], F [I + . 1 ] [J-WW [ID [I]]] + VV [ID [I]]); // draw key 99 the else F [I] [J] = F [I + SIZ [ID [I]]] [J]; // draw focus particular emphasis ------ 100 } 101 the printf ( " % D \ n- " , F [ . 1 ] [m]); // key stroke 102 return 0 ; 103 }
This question makes me tune the afternoon of the reasons was actually ........................ Tarjan wrong. .