zoukankan      html  css  js  c++  java
  • 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!
    ");
    79         continue;
    80      }
    81      dfs(1,0);
    82      printf("%d
    ",f[1][m]);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    Linux命令-压缩解压命令:gzip、gunzip
    Linux命令-用户管理命令:useradd,passwd,who,w
    Linux命令-帮助命令:help
    Linux命令-帮助命令:whatis,apropos
    Linux命令-帮助命令:man
    Linux命令-文件搜索命令:grep
    Linux命令-文件搜索命令:whereis
    Linux命令-文件搜索命令:which
    Linux命令-文件搜索命令:locate
    Linux命令-文件搜索命令:find
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5553887.html
Copyright © 2011-2022 走看看