1 条题解

  • 5
    @ 2025-2-10 19:53:21

    本蒟蒻实在没有想到怎么用背包去做........那 就只好写树形dp了 直接上代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,w[201],c[201],x,f[201][40001];
    int head[200];//链式前向星头结点(第一条边) 
    int k,ans;
    struct edge{
    	int to;//这条边到达的点 
    	int next;//下一条边的编号
    }e[201];
    
    inline void add(int u,int v){//建树(双向边) 
    	e[++k].to=v;
    	e[k].next=head[u];
    	head[u]=k;
    	e[++k].to=u;
    	e[k].next=head[v];
    	head[v]=k;
    }
    
    void dfs(int u/*当前节点*/,int t/*当前容量*/,int fat/*父亲节点*/){ 
    	if(t<=0) return ;//存不下了 
    	for(int i=head[u];i;i=e[i].next)/*遍历这棵树*/{
    		int v=e[i].to;
    		if(v==fat) continue;//如果是父节点直接跳过 
    		for(int k=n-w[v];k>=0;k--){
    			f[v][k]=f[u][k]+c[v];//如果选子树必须选这个节点 
    		}
    		dfs(v,t-w[v],u);//继续递归 
    		for(int k=n;k>=w[v];k--){
    			f[u][k]=max(f[u][k],f[v][k-w[v]]);//01背包选或不选 
    		}
    	}
    	return; 
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&w[i],&c[i],&x);
    		c[i]*=w[i];
    		add(i,x);
    	}
    	dfs(0,n,-1);//0为根节点,递归dp 
    	for(int i=0;i<=n;i++){
    		ans=max(ans,f[0][i]);
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 1

信息

ID
152
时间
1000ms
内存
125MiB
难度
8
标签
递交数
30
已通过
7
上传者