zoukankan      html  css  js  c++  java
  • HDU 3899 树形DP||树上递推

    JLUCPC

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=3899

    Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1375    Accepted Submission(s): 413


    Problem Description
    Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Contest. The contest was always held in the college of software in the past. However, they changed their minds and decided to find the most convenient location from all colleges this year.
    Each college in JLU is located in one of the N (1 <= N <= 100,000) different locations (labeled as 1 to N) connected by N-1 roads. Any two colleges are reachable to each other. The Contest can be held at any one of these N colleges. Moreover, Road i connects college A_i and B_i (1 <= A_i <=N; 1 <= B_i <= N) and has length L_i (1 <= L_i <= 1,000). College i has T_i (0 <= T_i <= 1,000) teams participating in the contest.
    When choosing the college to hold the Contest, Dr. Skywind wishes to minimize the inconvenience of the chosen location. The inconvenience of choosing college P is the sum of the distance that all teams need to reach college P (i.e., if the distance from college i to college P is 20, then the travel distance is T_i*20). Please help Dr. Skywind and Dr. Walkoncloud to choose the most convenient location for the contest.
     
    Input
    There are multiple test cases. For each case, the first line contains a single integer N, indicating the number of colleges. The next N lines describes T_1 to T_n. Then, each of the last N-1 lines will contain 3 integers, namely A_i, B_i and L_i.
     
    Output
    For each case, output the minimum inconvenience possible
     
    Sample Input
    3 1 1 2 1 2 2 2 3 1 4 100 1 1 1 1 2 1 2 3 1 2 4 1
     
    Sample Output
    4 5

     题意:

    给定N个节点的点权Ti[i],N-1条边的权值,以某点为根的代价是,所有点的点权值*到树根的距离,找出最小的代价。

    Hint:

    树上递推

    假设求得以a为树根的总代价,b是a的子节点,tot是树的总点权值,则以b为树根的代价,与a相比

    多了tot-size[b] 少了size[a] 倍的edge(a,b)

    递推写法:

    #include<bits/stdc++.h>
    #define Pii pair<int,long long>
    #define fi first
    #define se second
    #define INF 0x7fffffff
    #define pb push_back
    #define mp make_pair
    #define maxn 101000
    #define LL long long 
    using namespace std;
    vector<Pii> G[maxn];
    int n,m,Ti[maxn],size[maxn];
    LL tot,res=0,ans=0;
    void dfs(int x,int fa,LL cnt){
        Pii now;
        size[x]=Ti[x];
        ans+=cnt*Ti[x];
        for(int i=0;i<G[x].size();i++){
            now=G[x][i];
            if(now.fi==fa) continue;
            dfs(now.fi,x,cnt+now.se);
            size[x]+=size[now.fi]; 
        }
    }
    void solve(int x,int fa,LL cnt){
        ans=min(ans,cnt);
        Pii now;
        for(int i=0;i<G[x].size();i++){
            now=G[x][i];
            if(now.fi==fa) continue;
            solve(now.fi,x,cnt+now.se*(tot-2*size[now.fi])); 
        }
    }
    int main(){
        int T;
        int u,v,w;
        while(scanf("%d",&n)!=EOF){
            tot=0;
            for(int i=1;i<=n;i++) cin>>Ti[i],tot+=Ti[i];
            for(int i=1;i<n;i++){
                cin>>u>>v>>w;
                G[u].pb(mp(v,w));
                G[v].pb(mp(u,w));
            }
            ans=0;
            dfs(1,-1,0);
            solve(1,-1,ans);
            cout<<ans<<endl;
            for(int i=1;i<=n;i++) G[i].clear();
        }
        return 0;
    }

    DP写法:

     1 #include<bits/stdc++.h>
     2 #define Pii pair<int,long long>
     3 #define fi first
     4 #define se second
     5 #define INF 0x7fffffff
     6 #define pb push_back
     7 #define mp make_pair
     8 #define maxn 101000
     9 #define LL long long 
    10 using namespace std;
    11 vector<Pii> G[maxn];
    12 int n,m,Ti[maxn],size[maxn];
    13 LL tot,res=0,ans=0,dp[maxn];
    14 void dfs(int x,int fa,LL cnt){
    15     Pii now;
    16     size[x]=Ti[x];
    17     ans+=cnt*Ti[x];
    18     for(int i=0;i<G[x].size();i++){
    19         now=G[x][i];
    20         if(now.fi==fa) continue;
    21         dfs(now.fi,x,cnt+now.se);
    22         size[x]+=size[now.fi]; 
    23     }
    24 }
    25 void solve(int x,int fa){
    26     Pii now;
    27     for(int i=0;i<G[x].size();i++){
    28         now=G[x][i];
    29         if(now.fi==fa) continue;
    30         dp[now.fi]=dp[x]+now.se*(tot-2*size[now.fi]);
    31         solve(now.fi,x); 
    32     }
    33 }
    34 int main(){
    35     int T;
    36     int u,v,w;
    37     while(scanf("%d",&n)!=EOF){
    38         tot=0;
    39         for(int i=1;i<=n;i++) cin>>Ti[i],tot+=Ti[i];
    40         for(int i=1;i<n;i++){
    41             cin>>u>>v>>w;
    42             G[u].pb(mp(v,w));
    43             G[v].pb(mp(u,w));
    44         }
    45         ans=0;
    46         dfs(1,-1,0);
    47         dp[1]=ans;
    48         solve(1,-1);
    49         for(int i=1;i<=n;i++) ans=min(ans,dp[i]);
    50         cout<<ans<<endl;
    51         for(int i=1;i<=n;i++) G[i].clear(),dp[i]=0;
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    WCF Security系列(1)Security概述
    转:如何修复Team Foundation Server Workgroup Edition 不小心删除了所有Team Foundation Licensed Users组内用户问题
    转:最真实的2006年应届毕业生真实薪水
    如果为网站生成自签名SSL证书
    转 :TFS(Team Foundation Server)使用经验
    The sequence 2 序列2 攻略 (第4049关)
    力扣 223. 矩形面积
    The sequence 2 序列2 攻略 (第5059关)
    The sequence 2攻略 序列2攻略(第3039关)
    题解 P1147 【连续自然数和】
  • 原文地址:https://www.cnblogs.com/poler/p/7258008.html
Copyright © 2011-2022 走看看