• hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)


    题目链接:

    Magic boy Bi Luo with his excited tree

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1037    Accepted Submission(s): 298


    Problem Description
    Bi Luo is a magic boy, he also has a migic tree, the tree has N nodes , in each node , there is a treasure, it's value is V[i], and for each edge, there is a cost C[i], which means every time you pass the edge i , you need to pay C[i].

    You may attention that every V[i] can be taken only once, but for some C[i] , you may cost severial times.

    Now, Bi Luo define ans[i] as the most value can Bi Luo gets if Bi Luo starts at node i.

    Bi Luo is also an excited boy, now he wants to know every ans[i], can you help him?
     
    Input
    First line is a positive integer T(T104) , represents there are T test cases.

    Four each test:

    The first line contain an integer N(N105).

    The next line contains N integers V[i], which means the treasure’s value of node i(1V[i]104).

    For the next N1 lines, each contains three integers u,v,c , which means node u and node v are connected by an edge, it's cost is c(1c104).

    You can assume that the sum of N will not exceed 106.
     
    Output
    For the i-th test case , first output Case #i: in a single line , then output N lines , for the i-th line , output ans[i] in a single line.
     
    Sample Input
    1
    5
    4 1 7 7 7
    1 2 6
    1 3 1
    2 4 8
    3 5 2
     
    Sample Output
    Case #1:
    15
    10
    14
    9
    15
     
    题意:
     
    每个节点有价值v[i]的宝物,但是任何两个节点u,v之间的路走一次花费为w,从每个节点出发最多可以赚多少钱;
     
    思路:
     
    树形dp的题目,需要记录转移的最大和次大,注意转移的情况,不能写漏了;
     
    AC代码:
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    #include <map>
      
    using namespace std;
      
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
      
    typedef  long long LL;
      
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
      
    const int mod=1e9+7;
    const double PI=acos(-1.0);
    const int inf=1e9;
    const int N=(1<<20)+10;
    const int maxn=1e5+110;
    const double eps=1e-12;
     
    
    int n,cnt,head[maxn],a[maxn];
    int down[maxn][2],up[maxn][2],max1[maxn],max2[maxn],temp[maxn],cost[maxn];
    struct Edge
    {
        int from,to,next,val;
    }edge[2*maxn];
    inline void add_edge(int s,int e,int va)
    {
        edge[cnt].from=s;
        edge[cnt].to=e;
        edge[cnt].next=head[s];
        edge[cnt].val=va;
        head[s]=cnt++;
    }
    inline void Init()
    {
        cnt=0;
        for(int i=0;i<=n;i++)head[i]=-1;
    }
    void dfs(int cur,int fa,int va)
    {
        down[cur][1]=a[cur];
        cost[cur]=va;
        for(int i=head[cur];i!=-1;i=edge[i].next)
        {
            int x=edge[i].to;
            if(x==fa)continue;
            dfs(x,cur,edge[i].val);
            if(down[x][1]-2*edge[i].val>=0)down[cur][1]+=down[x][1]-2*edge[i].val;
        }
    }
    void dfs1(int cur,int fa)
    {
        down[cur][0]=a[cur];
        temp[cur]=max1[cur]=max2[cur]=0;
        for(int i=head[cur];i!=-1;i=edge[i].next)
        {
            int x=edge[i].to;
            if(x==fa)continue;
            dfs1(x,cur);
            if(down[x][0]-edge[i].val>0)
            {
                int t=down[cur][1];
                if(down[x][1]-2*edge[i].val>=0)t-=down[x][1]-2*edge[i].val;
                t+=down[x][0]-edge[i].val;
                    if(t>=down[cur][0])
                    {
                        max2[cur]=max1[cur];
                        temp[cur]=down[cur][0];
                        down[cur][0]=t;
                        max1[cur]=x;
                    }
                    else if(t>temp[cur])
                    {
                        max2[cur]=x;
                        temp[cur]=t;
                    }
            }
        }
    }
    
    void dfs2(int cur,int fa,int va)
    {
        up[cur][1]=0;
        if(down[cur][1]-2*va>=0)up[cur][1]=max(up[cur][1],down[fa][1]-down[cur][1]+2*va+up[fa][1]-2*va);
        else up[cur][1]=max(up[cur][1],down[fa][1]+up[fa][1]-2*va);
    
        up[cur][0]=0;
        if(max1[fa]==cur)
        {
            int t=down[fa][0]-down[cur][0]+va;
            up[cur][0]=max(up[cur][0],t+up[fa][0]-va);
            int r=max2[fa];
            if(down[r][1]-2*cost[r]>0)t=t-down[r][1]+2*cost[r];
            t+=down[r][0]-cost[r];
            up[cur][0]=max(up[cur][0],t+up[fa][1]-va);
        }
        else 
        {
    
            int t=down[fa][0];
            if(down[cur][1]-2*va>0)t-=down[cur][1]-2*va;
            up[cur][0]=max(up[cur][0],t+up[fa][1]-va);
            t=down[fa][1];
            if(down[cur][1]-2*va>0)t-=down[cur][1]-2*va;
            up[cur][0]=max(up[cur][0],t+up[fa][0]-va);
        }
        for(int i=head[cur];i!=-1;i=edge[i].next)
        {
            int x=edge[i].to;
            if(x==fa)continue;
            dfs2(x,cur,edge[i].val);
        }
    }
    
    int main()
    {
        int t,Case=0;
        read(t);
        while(t--)
        {
            read(n);Init();
            For(i,1,n)read(a[i]);
            int u,v,w;
            For(i,1,n-1)
            {
                read(u);read(v);read(w);
                add_edge(u,v,w);
                add_edge(v,u,w);
            }
            dfs(1,0,0);
            dfs1(1,0);
            dfs2(1,0,0);
            printf("Case #%d:
    ",++Case);
            for(int i=1;i<=n;i++)printf("%d
    ",max(down[i][0]+up[i][1],down[i][1]+up[i][0]));
        }    
        return 0;
    }
    

      

  • 相关阅读:
    hibernate关联总结
    hibernate关联映射之多对多
    hibernate关联映射之一对多&多对一
    hibernate集合映射
    Hibernate3疑惑解决
    Hibernate3运行原理
    Hibernate3映射数据类型
    Hibernate3主键生成策略
    Hibernate3核心API简介-Transaction接口
    Hibernate3核心API-Session接口
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5856654.html
Copyright © 2020-2023  润新知