ZOJ 3626 Treasure Hunt I(树型DP+01背包)

来源:互联网 发布:电脑系统优化软件排行 编辑:程序博客网 时间:2024/06/05 22:17

题意:给一棵有n个结点的树,每个点有点权表示在这个点上的价值,每条边有边权表示走这条路所需要的时候,给一个时间m,问在时间m从点k出发再回到点k所能得到的最大的价值和。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N=105;int n,m,k;int data[N],head[N],tot;int dp[N][205];struct Edge{int to,valu,pre;Edge(){}Edge(int a,int b,int c){to=a;valu=b;pre=c;}}edge[N];void addEdge(int a,int b,int c){edge[tot]=Edge(b,c,head[a]);head[a]=tot++;}void dfs(int u,int fa,int day){for(int i=head[u];i!=-1;i=edge[i].pre){int v=edge[i].to,valu=edge[i].valu;if(v==fa) continue;dfs(v,u,day-edge[i].valu);for(int j=day;j>=0;j--){for(int k=0;k+valu<=j;k++){if(dp[v][k]!=-1&&dp[u][j-k-valu]!=-1){dp[u][j]=max(dp[u][j],dp[u][j-k-valu]+dp[v][k]);}}}}}int main(){while(scanf("%d",&n)!=EOF){tot=0;memset(head,-1,sizeof(head));memset(dp,-1,sizeof(dp));for(int i=1;i<=n;i++){scanf("%d",&data[i]);dp[i][0]=data[i];}for(int i=0;i<n-1;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);addEdge(a,b,c);addEdge(b,a,c);}scanf("%d%d",&k,&m);m/=2;dfs(k,-1,m);int res=0;for(int i=0;i<=m;i++) res=max(res,dp[k][i]);printf("%d\n",res);}return 0;}



原创粉丝点击