zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Android Market google play store帐号注册方法流程 及发布应用注意事项【转载】
    cocos2d-x 调用第三方so文件
    ios cocos2d-x 多点触摸
    linux文件分割(将大的日志文件分割成小的)
    Linux 统计某个字符串出现的次数
    scapy基础-网络数据包结构
    mac 下idea光标问题
    mac ox终端显示 bogon的问题
    hibernate和mybatis的区别
    memcached知识点梳理
  • 原文地址:https://www.cnblogs.com/jihe/p/6007339.html
Copyright © 2011-2022 走看看