先将1到n的路径上的点进行缩点,总时间减去该路径长度,然后这道题就和ZOJ 3626一模一样了,也就是,树形DP。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int head[200],nc,dp[200][600],v[200]; 6 struct edge 7 { 8 int to,cost,next; 9 }edge[1000]; 10 struct data 11 { 12 int a,b,c; 13 }data[200]; 14 void add(int a,int b,int c) 15 { 16 edge[nc].to=b;edge[nc].next=head[a];edge[nc].cost=c;head[a]=nc++; 17 edge[nc].to=a;edge[nc].next=head[b];edge[nc].cost=c;head[b]=nc++; 18 } 19 int n,t; 20 int tpcnt; 21 bool mark[200]; 22 void dfs1(int now,int fa) 23 { 24 if(now==n) 25 { 26 mark[now]=true; 27 return; 28 } 29 for(int i=head[now];i!=-1;i=edge[i].next) 30 { 31 int to=edge[i].to; 32 if(to!=fa) 33 { 34 dfs1(to,now); 35 if(mark[to]) 36 mark[now]=true,tpcnt+=edge[i].cost; 37 } 38 } 39 } 40 void dfs(int now) 41 { 42 int i,j,k,to,cost,val; 43 mark[now]=true; 44 val=v[now]; 45 for(i=0;i<=t;i++) 46 dp[now][i]=val; 47 for(i=head[now];i!=-1;i=edge[i].next) 48 { 49 to=edge[i].to; 50 cost=edge[i].cost; 51 if(mark[to]) 52 continue; 53 dfs(to); 54 for(k=t;k>=2*cost;k--) 55 { 56 for(j=0;j<=k-2*cost;j++) 57 dp[now][k]=max(dp[now][k],dp[now][k-2*cost-j]+dp[to][j]); 58 } 59 } 60 } 61 int main() 62 { 63 while(scanf("%d%d",&n,&t)!=EOF) 64 { 65 memset(head,-1,sizeof(head)); 66 nc=0; 67 for(int i=0;i<n-1;i++) 68 { 69 scanf("%d%d%d",&data[i].a,&data[i].b,&data[i].c); 70 add(data[i].a,data[i].b,data[i].c); 71 } 72 for(int i=1;i<=n;i++) 73 scanf("%d",v+i); 74 memset(mark,false,sizeof(mark)); 75 mark[n]=true; 76 tpcnt=0; 77 dfs1(1,1); 78 t-=tpcnt; 79 if(t<0) 80 { 81 printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n"); 82 continue; 83 } 84 int ans=0; 85 memset(head,-1,sizeof(head)); 86 nc=0; 87 for(int i=1;i<=n;i++) 88 if(mark[i]) 89 ans+=v[i]; 90 v[0]=ans; 91 for(int i=0;i<n-1;i++) 92 { 93 int a=data[i].a,b=data[i].b,c=data[i].c; 94 if(!mark[a]||!mark[b]) 95 { 96 if(mark[a]) 97 add(0,b,c); 98 else if(mark[b]) 99 add(0,a,c); 100 else 101 add(a,b,c); 102 } 103 } 104 memset(dp,0,sizeof(dp)); 105 memset(mark,false,sizeof(mark)); 106 dfs(0); 107 printf("%d\n",dp[0][t]); 108 } 109 return 0; 110 }