2 条题解

  • 0
    @ 2025-11-24 11:26:41
    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e4+10,W=6e4+10;
    vector<int>dp[N];
    int n,m,siz[N],rdfn[N],len,w[N],v[N],d[N];vector<int>G[N];
    void dfs(int x,int f)
    {
    //	printf("%d %d\n",x,f);
    	siz[x]=1;
    	for(int y:G[x])if(y!=f)
    	{
    		dfs(y,x);
    		siz[x]+=siz[y];
    	}
    	rdfn[++len]=x;
    }
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>d[i];
    		G[d[i]].push_back(i);
    	}
    	for(int i=1;i<=n;i++)cin>>w[i];
    	for(int i=1;i<=n;i++)cin>>v[i];
    	for(int i=0;i<=n+2;i++)dp[i].resize(m+2);
    	dfs(0,0);
    	for(int i=1;i<=len;++i)
    	{
            int x=rdfn[i];
    //        printf("%d %d\n",i,x);
    		for(int j=0;j<=m;++j)
    		{
                dp[i][j]=dp[i-siz[x]][j];
                if(j>=w[x])dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+v[x]);
            }
        } 
    //    cout<<6;return 0;
        int ans=0;
        for(int i=1;i<=m;i++)ans=max(ans,dp[n][i]);
        cout<<ans;
        return 0;
    }
    
    
    • 0
      @ 2025-10-8 16:50:07

      decltype版本:

      #include <bits/stdc++.h>
      using namespace std;
      const int T=6.06e7+10,N=5e4+10;
      int n,W,ff[T],w[N],v[N],s[N],ww[N],vv[N],ss[N],id;
      vector<int>G[N]; 
      void dfs(int x,int fa)
      {
          s[x]=1;
          for(int y:G[x])if(y!=fa)   
          {
             dfs(y,x);
             s[x]+=s[y];
          }
          ++id;
          ww[id]=w[x];
          vv[id]=v[x];
          ss[id]=s[x];
      }
      signed main()
      {
          scanf("%d%d",&n,&W);
          int (&f)[n+2][W+1]=decltype(f)(ff);
          for(int i=1,y;i<=n;++i)
          {
              scanf("%d",&y);
              G[i].push_back(y);
              G[y].push_back(i);
          }
          for(int i=1;i<=n;++i)scanf("%d",&w[i]);
          for(int i=1;i<=n;++i)scanf("%d",&v[i]);    
          id=0;dfs(0,0);
          memset(f,0,sizeof(f));
          for(int i=1;i<=id;++i)
          {
              for(int j=0;j<=W;++j)
              {
                  f[i][j]=f[i-ss[i]][j];
                  if(j>=ww[i])f[i][j]=max(f[i][j],f[i-1][j-ww[i]]+vv[i]);
              }
          }
          printf("%d\n",f[id][W]);
          return 0;
      }
      

      版本二:

      #include <bits/stdc++.h>
      using namespace std;
      const int T=6.06e7+10,N=5e4+10;
      int n,W,f[T],w[N],v[N],s[N],ww[N],vv[N],ss[N],id;
      int gid(int x,int y){ return x*(W+1)+y; }//此处不能写 x*W+y ,每行有效列为0~W
      vector<int>G[N]; 
      void dfs(int x,int fa)
      {
          s[x]=1;
          for(int y:G[x])if(y!=fa)   
          {
             dfs(y,x);
             s[x]+=s[y];
          }
          ++id;
          ww[id]=w[x];
          vv[id]=v[x];
          ss[id]=s[x];
      }
      signed main()
      {
          scanf("%d%d",&n,&W);
          for(int i=1,y;i<=n;++i)
          {
              scanf("%d",&y);
              G[i].push_back(y);
              G[y].push_back(i);
          }
          for(int i=1;i<=n;++i)scanf("%d",&w[i]);
          for(int i=1;i<=n;++i)scanf("%d",&v[i]);    
          id=0;dfs(0,0);
          memset(f,0,sizeof(f));
          for(int i=1;i<=id;++i)
          {
              for(int j=0;j<=W;++j)
              {
                  f[gid(i,j)]=f[gid(i-ss[i],j)];
                  if(j>=ww[i])f[gid(i,j)]=max(f[gid(i,j)],f[gid(i-1,j-ww[i])]+vv[i]);
              }
          }
          printf("%d\n",f[gid(id,W)]);
          return 0;
      }
      
      • 1

      *【树形DP:树上背包】树形背包传统[LOJ160]

      信息

      ID
      371
      时间
      600ms
      内存
      512MiB
      难度
      8
      标签
      递交数
      295
      已通过
      35
      上传者