• hdu 5834


    题意:有n个点的树,边上有值w,每次经过这条边,都要花费w,每个点有一个值,到达过该点可以获得该值,每个点只能获得一次,求从每个点出发,所能获得的最大值分析:选择一个点作为根,那么每个考虑从每个点走向子树和走向父亲,回来和不回来的最大值,答案就说max(儿子回来+父亲不回来,父亲回来+儿子不回来),走向儿子的好求,只是走向父亲的难求一些,但是加上一点,就是考虑父亲是不是有必要向当前的儿子走和不回来的儿子是不是该点就好求了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+5;
     4 //Ê÷
     5 int head[maxn],to[maxn*2],nxt[maxn*2],tot,cost[maxn*2];
     6 void addedge(int u,int v,int w){
     7     ++tot;
     8     nxt[tot]=head[u];
     9     to[tot]=v;
    10     cost[tot]=w;
    11     head[u]=tot;
    12 }
    13 
    14 int val[maxn],dp[maxn][2],fa[maxn][2],p[maxn],fp[maxn];
    15 int n,t;
    16 
    17 void dfs1(int u,int f){
    18     dp[u][0]=dp[u][1]=val[u];p[u]=f;fp[u]=u;
    19     for(int i=head[u];~i;i=nxt[i]){
    20         int v=to[i],w=cost[i];if(v==f)continue;
    21         dfs1(v,u);
    22         dp[u][1]+=max(0,dp[v][0]-2*w);
    23         if(dp[u][1]<dp[u][0]+dp[v][1]-w)
    24             fp[u]=v,dp[u][1]=dp[u][0]+dp[v][1]-w;
    25         dp[u][0]+=max(0,dp[v][0]-2*w);
    26     }
    27 }
    28 
    29 void dfs2(int u,int f,int d){
    30     fa[u][0]=fa[u][1]=0;
    31     if(dp[u][0]<=2*d){
    32         fa[u][0]=max(0,fa[f][0]+dp[f][0]-2*d);
    33         fa[u][1]=max(0,fa[f][1]+dp[f][0]-d);
    34     }
    35     else{
    36         fa[u][0]=max(0,fa[f][0]+dp[f][0]-dp[u][0]);
    37         fa[u][1]=max(0,fa[f][1]+dp[f][0]-dp[u][0]+d);
    38     }
    39     if(fp[f]==u){
    40         int mx1=val[f],mx2=val[f];
    41         for(int i=head[f];~i;i=nxt[i]){
    42             int v=to[i],w=cost[i];
    43             if(v==p[f]||v==u)continue;
    44             mx1=max(mx1,mx1+dp[v][0]-2*w);
    45             mx1=max(mx1,mx2+dp[v][1]-w);
    46             mx2+=max(0,dp[v][0]-2*w);
    47         }
    48         fa[u][1]=max(fa[u][1],mx1+fa[f][0]-d);
    49     }
    50     else{
    51         if(dp[u][0]>=2*d)
    52             fa[u][1]=max(fa[u][1],fa[f][0]+dp[f][1]-dp[u][0]+d);
    53         else
    54             fa[u][1]=max(fa[u][1],fa[f][0]+dp[f][1]-d);
    55     }
    56     for(int i=head[u];~i;i=nxt[i])
    57         if(to[i]!=f)dfs2(to[i],u,cost[i]);
    58 }
    59 
    60 void init(){
    61     tot=0;
    62     memset(head,-1,sizeof(head));
    63 }
    64 
    65 int main(){
    66     scanf("%d",&t);
    67     int cas=1;
    68     while(t--){
    69         scanf("%d",&n);
    70         for(int i=1;i<=n;i++)scanf("%d",val+i);
    71         init();
    72         for(int i=1;i<n;i++){
    73             int u,v,w;scanf("%d%d%d",&u,&v,&w);
    74             addedge(u,v,w);addedge(v,u,w);
    75         }
    76         dfs1(1,0);
    77         dfs2(1,0,0);
    78         printf("Case #%d:
    ",cas++);
    79         for(int i=1;i<=n;i++)
    80             printf("%d
    ",max(dp[i][0]+fa[i][1],dp[i][1]+fa[i][0]));
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    Linux机器学习软件配置
    安装linux14.04
    Navicat无法连接SqlServer数据库
    linux命令行安装teamviewer
    Ubuntu14.04+Dell 7060安装无线/有线网络驱动
    启动一个SpringBoot的maven项目
    HTML5新增特性
    HTML 表格|表单
    HTML 基础
    初识 wijmo-grid
  • 原文地址:https://www.cnblogs.com/jihe/p/6007339.html
Copyright © 2020-2023  润新知