zoukankan      html  css  js  c++  java
  • BZOJ-1827 [Usaco2010 Mar]gather 奶牛大集会

    1827: [Usaco2010 Mar]gather 奶牛大集会

    Time Limit: 1 Sec  Memory Limit: 64 MB

    Description

    Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。每个奶牛居住在 N(1<=N<=100,000) 个农场中的一个,这些农场由N-1条道路连接,并且从任意一个农场都能够到达另外一个农场。道路i连接农场A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),长度为L_i(1 <= L_i <= 1,000)。集会可以在N个农场中的任意一个举行。另外,每个牛棚中居住者C_i(0 <= C_i <= 1,000)只奶牛。在选择集会的地点的时候,Bessie希望最大化方便的程度(也就是最小化不方便程度)。比如选择第X个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和,(比如,农场i到达农场X的距离是20,那么总路程就是C_i*20)。帮助Bessie找出最方便的地点来举行大集会。 考虑一个由五个农场组成的国家,分别由长度各异的道路连接起来。在所有农场中,3号和4号没有奶牛居住。

    Input

    第一行:一个整数N * 第二到N+1行:第i+1行有一个整数C_i * 第N+2行到2*N行,第i+N+1行为3个整数:A_i,B_i和L_i。

    Output

    * 第一行:一个值,表示最小的不方便值。

    Sample Input

    5
    1
    1
    0
    0
    2
    1 3 1
    2 3 2
    3 4 3
    4 5 3

    Sample Output

    15

    HINT

    题解

    树形DP。

    对于一个点,记录Tot(点权总和),Sum[i](所有子节点(包括自己)的点权和),Down[i](所有子节点到点i的花费和),Up[i](非点i子节点到点i的花费和)。那么一个点i的花费就是Up[i] + Down[i]。

    进行两遍深搜。                                                                                   

    第一遍:处理出Sum[]和Down[](Sum[X] =Sigma {Sum[son]} + Num[X],Down[X] =Sigma {Down[son] + Sum[son] * E[i].W})                                                                          

    第二遍:处理出Up[],比较Down[] + Up[]的值(Up[X] = Up[Fa] + Down[Fa] - Down[X] - Sum[X] * E[i].W + (Tot - Sum[X]) * E[i].W

    代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #define MAXN 1000100
     4 #define MAXM MAXN * 2
     5  
     6 struct EDGE {
     7     int To, Next, W;
     8 };
     9  
    10 int N;
    11 EDGE E[MAXM];
    12 int Last[MAXN], Top;
    13 int Tot;
    14 bool Vis[MAXN];
    15 int Num[MAXN], Sum[MAXN];
    16 long long Up[MAXN], Down[MAXN];
    17 long long Ans = -1;
    18  
    19 void Add(int A, int B, int C) {
    20     ++Top;
    21     E[Top].To = B;
    22     E[Top].Next = Last[A];
    23     E[Top].W = C;
    24     Last[A] = Top;
    25 }
    26  
    27 void DFS(int X) {
    28     Vis[X] = 1;
    29     for (int i = Last[X]; i; i = E[i].Next) {
    30         if (!Vis[E[i].To]) {
    31             DFS(E[i].To);
    32             Sum[X] += Sum[E[i].To];
    33             Down[X] += Down[E[i].To] + (long long) Sum[E[i].To] * E[i].W;
    34         }
    35     }
    36     Sum[X] += Num[X];
    37 }
    38  
    39 void Expand_Up(int X, int Fa, int V) {
    40     Vis[X] = 1;
    41     Up[X] = Up[Fa] + Down[Fa] - Down[X] - (long long) Sum[X] * V + (long long) (Tot - Sum[X]) * V;
    42     if (X == 1) Up[X] = 0;
    43     for (int i = Last[X]; i; i = E[i].Next) {
    44         if (E[i].To != Fa && !Vis[E[i].To]) Expand_Up(E[i].To, X, E[i].W);
    45     }
    46     if (Up[X] + Down[X] < Ans || Ans == -1) Ans = Up[X] + Down[X];
    47 }
    48  
    49 int main() {
    50     scanf("%d", &N);
    51     for (int i = 1; i <= N; ++i) {
    52         scanf("%d", &Num[i]);
    53         Tot += Num[i];
    54     }
    55     for (int i = 1; i < N; ++i) {
    56         int A, B, C;
    57         scanf("%d%d%d", &A, &B, &C);
    58         Add(A, B, C);
    59         Add(B, A, C);
    60     }
    61     DFS(1);
    62     memset(Vis, 0, sizeof(Vis));
    63     Expand_Up(1,0,0);
    64     printf("%lld
    ", Ans);
    65 }
  • 相关阅读:
    恶意代码检测--已看梳理
    tips
    十大排序
    python使用记录
    Matlab用figure;subplot后合并子图
    利用python的docx模块处理word和WPS的docx格式文件
    论文笔记(FCN网络,语义分割):Fully Convolutional Networks for Semantic Segmentation
    论文笔记:SoundNet: Learning Sound Representations from Unlabeled Video
    Winner-Take-All Autoencoders ( 赢者通吃自编码器)
    机器学习优化过程中的各种梯度下降方法(SGD,AdaGrad,RMSprop,AdaDelta,Adam,Momentum,Nesterov)
  • 原文地址:https://www.cnblogs.com/DonMaestro/p/4322293.html
Copyright © 2011-2022 走看看