zoukankan      html  css  js  c++  java
  • hdu 3899(树形dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3899

    思路:num[u]表示u以及u的子树的队伍数的总和,dist[u]表示u到根节点的距离,dp[u]表示以u为根时的总花费。我们可以先做一次dfs算出树上所有点到根节点(1)的花费总和,然后同时计算出num[],然后就是又一次dfs算出以每个点为根的话费,这里有dp[v]=dp[u]+(sum-num[v])*w-num[v]*w(其中u是v的根)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 #define MAXN 100100
     8 typedef long long LL;
     9 #pragma comment(linker, "/STACK:1024000000,1024000000")
    10 
    11 struct Edge{
    12     int v,w;
    13     Edge(int vv,int ww):v(vv),w(ww){}
    14 };
    15 
    16 int n;
    17 int num[MAXN],sum;
    18 LL dp[MAXN],dist[MAXN],ans;
    19 vector<vector<Edge> >G;
    20 
    21 void dfs1(int u,int father)
    22 {
    23     for(int i=0;i<G[u].size();i++){
    24         int v=G[u][i].v,w=G[u][i].w;
    25         if(v==father)continue;
    26         dist[v]=dist[u]+w;
    27         ans+=(LL)num[v]*dist[v];
    28         dfs1(v,u);
    29         num[u]+=num[v];
    30     }
    31 }
    32 
    33 void dfs2(int u,int father)
    34 {
    35     for(int i=0;i<G[u].size();i++){
    36         int v=G[u][i].v,w=G[u][i].w;
    37         if(v==father)continue;
    38         dp[v]=dp[u]+(LL)(sum-num[v])*w-(LL)num[v]*w;
    39         dfs2(v,u);
    40     }
    41 }
    42 
    43 
    44 int main()
    45 {
    46     int u,v,w;
    47     while(~scanf("%d",&n)){
    48         G.clear();
    49         G.resize(n+2);
    50         sum=0;
    51         for(int i=1;i<=n;i++){
    52             scanf("%d",&num[i]);
    53             sum+=num[i];
    54         }
    55         for(int i=1;i<n;i++){
    56             scanf("%d%d%d",&u,&v,&w);
    57             G[u].push_back(Edge(v,w));
    58             G[v].push_back(Edge(u,w));
    59         }
    60         dist[1]=0;
    61         ans=0;
    62         dfs1(1,-1);
    63         memset(dp,0,sizeof(dp));
    64         dp[1]=ans;
    65         dfs2(1,-1);
    66 //        cout<<ans<<"**"<<endl;
    67         for(int i=2;i<=n;i++){
    68             ans=min(ans,dp[i]);
    69 //            cout<<dp[i]<<"***"<<endl;
    70         }
    71         printf("%I64d
    ",ans);
    72     }
    73     return 0;
    74 }
    75 
    76         
    View Code
  • 相关阅读:
    内置常量
    python100练
    python之禅
    Django
    pymsql入门
    jQuery事件
    数据库(索引)
    算法基础知识
    数据库(查询专项)
    数据库(所有人都坐下!这是基本操作!)
  • 原文地址:https://www.cnblogs.com/wally/p/3310785.html
Copyright © 2011-2022 走看看