zoukankan      html  css  js  c++  java
  • 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree

     1 // 树形DP CCPC网络赛  HDU5834 Magic boy Bi Luo with his excited tree
     2 // 题意:n个点的树,每个节点有权值为正,只能用一次,每条边有负权,可以走多次,问从每个点出发的最大获益
     3 // 思路:
     4 // dp[i]: 从i点出发回到i点的最大值
     5 // d[i][0] 从i点出发不回来的最大值
     6 // d[i][1] 从i点出发取最大值的下一个点
     7 // d[i][2] 从i点出发取次大值
     8 // dfs1处理出这四个
     9 // 然后,从1开始转移,分别DP求子节点从父亲转移过来的最大值,和从父亲出去不回来的最大值
    10 
    11 #include <bits/stdc++.h>
    12 using namespace std;
    13 #define LL long long
    14 const double inf = 123456789012345.0;
    15 const LL MOD =100000000LL;
    16 const int N =1e5+10;;
    17 #define clc(a,b) memset(a,b,sizeof(a))
    18 const double eps = 1e-7;
    19 void fre() {freopen("in.txt","r",stdin);}
    20 void freout() {freopen("out.txt","w",stdout);}
    21 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
    22 
    23 vector<pair<int,int> > g[N];
    24 int a[N],ans[N];
    25 int dp[N],d[N][3];
    26 void dfs1(int u,int f){
    27     dp[u]=a[u];
    28     for(int i=0;i<(int)g[u].size();i++){
    29        int v=g[u][i].first;
    30        int val=g[u][i].second;
    31        if(v==f) continue;
    32        dfs1(v,u);
    33        dp[u]+=max(0,dp[v]-2*val);
    34     } 
    35     d[u][0]=d[u][2]=a[u];
    36     d[u][1]=-1;
    37     for(int i=0;i<(int)g[u].size();i++){
    38         int v=g[u][i].first;
    39         int val=g[u][i].second;
    40         if(v==f) continue;
    41         int tem=dp[u]-max(0,dp[v]-2*val)+max(0,d[v][0]-val);//当前选择路径不回来的最大值
    42         if(tem>d[u][0]){
    43             d[u][2]=d[u][0];
    44             d[u][0]=tem;
    45             d[u][1]=i;
    46         }
    47         else if(tem>d[u][2]){
    48             d[u][2]=tem;
    49         }
    50     }
    51 }
    52 
    53 //no从父亲不回来的最大值,yes从父亲回来的最大值
    54 void dfs2(int u,int f,int no,int yes){
    55     ans[u]=max(dp[u]+no,yes+d[u][0]);
    56     for(int i=0;i<(int)g[u].size();i++){
    57         int v=g[u][i].first;
    58         int val=g[u][i].second;
    59         if(v==f) continue;
    60         int tem1,tem2;
    61         if(i==d[u][1]) tem1=max(0,d[u][2]-max(0,dp[v]-2*val));//从父亲出去但不是最优方案的最大值
    62         else tem1=max(0,d[u][0]-max(0,dp[v]-2*val));
    63         tem2=max(0,dp[u]-max(0,dp[v]-2*val));//从父亲出去又回来的最大值
    64         tem1=max(0,max(tem1+yes-val,tem2+no-val));//儿子节点从父亲转移过来的是 max(父亲儿子节点出去不回来+父亲的父亲出去回来的最大值,父亲儿子节点出去回来+父亲的父亲出去不回来的最大值)
    65         tem2=max(0,yes+tem2-2*val);
    66         dfs2(v,u,tem1,tem2);
    67     }
    68 }
    69 
    70 int main(){
    71     int T;
    72     scanf("%d",&T);
    73     for(int cas=1;cas<=T;cas++){
    74         int n;
    75         scanf("%d",&n);
    76         for(int i=1;i<=n;i++) g[i].clear();
    77         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    78         for(int i=1;i<n;i++){
    79             int u,v,x;
    80             scanf("%d%d%d",&u,&v,&x);
    81             g[u].push_back(make_pair(v,x));
    82             g[v].push_back(make_pair(u,x));
    83         }
    84         dfs1(1,-1);
    85         dfs2(1,-1,0,0);
    86         printf("Case #%d:
    ",cas);
    87         for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 选择排序
    Java实现 蓝桥杯VIP 算法提高 选择排序
    Java实现 蓝桥杯VIP 算法提高 选择排序
    QT中的SOCKET编程
    代理Delegate的小应用(使用setModelData设置下拉日期对话框)
    360企业云盘需求调研,包括定价
    大神为你分析 Go、Java、C 等主流编程语言(Go可以替代Java,而且最小化程序员的工作量,学习比较容易)
    VS 查看是否有内存泄露的方法
    SpringMVC之 数据绑定-1
    动画操作 (Applying Animations) ngAnimate12
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5782004.html
Copyright © 2011-2022 走看看