先将1到n的路径上的点进行缩点,总时间减去该路径长度,然后这道题就和ZOJ 3626一模一样了,也就是,树形DP。。

View Code
  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 }