HDU 4276 The Ghost Blows Light(树形)

题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T。问从1到达n在给定时间T内取得的最大价值?

思路:先从1走到n,如果总的时间不够走完,直接退出,否则把时间扣掉,这些边权设置为0,然后做一遍树形DP

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 int n,m;
 7 int tot,go[200005],first[200005],next[200005],val[200005];
 8 int c[200005],vis[200005],pre[200005],edge[200005],op[200005];
 9 int f[505][505],v[200005];
10 int read(){
11     int t=0,f=1;char ch=getchar();
12     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
13     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
14     return t*f;
15 }
16 void insert(int x,int y,int z){
17     tot++;
18     go[tot]=y;
19     next[tot]=first[x];
20     first[x]=tot;
21     val[tot]=z;
22 }
23 void add(int x,int y,int z){
24     insert(x,y,z);op[tot]=tot+1;
25     insert(y,x,z);op[tot]=tot-1;
26 }
27 void bfs(){
28     for (int i=1;i<=n;i++) vis[i]=pre[i]=edge[i]=0;
29     int h=0,t=1;
30     c[1]=1;vis[1]=1;
31     while (h<=t){
32         h++;
33         for (int i=first[c[h]];i;i=next[i]){
34             int pur=go[i];
35             if (vis[pur]) continue;
36             pre[pur]=c[h];
37             edge[pur]=i;
38             c[++t]=pur;
39             vis[pur]=1;
40         }
41     }
42 }
43 void prework(){
44     for (int i=n;i!=1;i=pre[i]){
45         m-=val[edge[i]];
46         val[edge[i]]=val[op[edge[i]]]=0;
47     }
48 }
49 void dfs(int x,int fa){
50     for (int i=0;i<=m;i++) f[x][i]=0;
51     for (int i=first[x];i;i=next[i]){
52         int pur=go[i];
53         if (pur==fa) continue;
54         dfs(pur,x);
55         int dis=val[i];
56         dis*=2;
57         for (int k=m;k>=dis;k--)
58          for (int j=0;j+dis<=k;j++)
59           f[x][k]=std::max(f[x][k],f[pur][j]+f[x][k-j-dis]);
60     }
61     for (int i=0;i<=m;i++)
62      f[x][i]+=v[x];
63 }
64 int main(){
65     while (scanf("%d%d",&n,&m)!=EOF){
66      if (n==0&&m==0) return 0;
67      tot=0;
68      for (int i=1;i<=n;i++) first[i]=0;
69      for (int i=1;i<n;i++){
70          int x,y,z;
71          x=read();y=read();z=read();
72          add(x,y,z);
73      }
74      for (int i=1;i<=n;i++) v[i]=read();
75      bfs();
76      prework();
77      if (m<0){
78         printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
79         continue;
80      }
81      dfs(1,0);
82      printf("%d\n",f[1][m]);
83     }
84     return 0;
85 }

 

posted @ 2016-06-02 17:46  GFY  阅读(151)  评论(0编辑  收藏  举报