About the tree backpack

  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 }
simple

 

  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 }
dfs order

This question makes me tune the afternoon of the reasons was actually ........................ Tarjan wrong. .

Guess you like

Origin www.cnblogs.com/sdfzjdx/p/11267590.html