• [Usaco2010 Mar]gather 奶牛大集会


    [Usaco2010 Mar]gather 奶牛大集会

    题目

    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

    OUTPUT

    15

    解题报告

    这破水题水了我一上午

    树规

    显然我们需要找出一个根来先算出一个不那么优的解,再去更新其他的解

    第一步很容易,第二步也很容易(我tm卡了一个上午)

    设目前的答案为$ans$,儿子节点的答案为$next$

    $$next=ans-size_{son} imes w_{i}+(tot-size_{son}) imes w_{i}$$

    显然我们可以用高深的数学知识乘法分配率把式子化简成这样:

    $$next=ans+(tot-2 imes size_{son}) imes w_{i}$$

    那么我们使$tot<2 imes size_{son}$,后面的式子就是负的,$ans$就被更新得更小了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 inline int read(){
     6     int sum(0);
     7     char ch(getchar());
     8     for(;ch<'0'||ch>'9';ch=getchar());
     9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    10     return sum;
    11 }
    12 struct edge{
    13     int e,w;
    14     edge *n;
    15 }a[200005],*pre[100005];
    16 int tot;
    17 inline void insert(int s,int e,int w){
    18     a[++tot].e=e;
    19     a[tot].w=w;
    20     a[tot].n=pre[s];
    21     pre[s]=&a[tot];
    22 }
    23 typedef long long L;
    24 int n;
    25 L c[100005],size[100005],dis[100005];
    26 L ans,sum;
    27 inline L dfs(int u,int fa){
    28     size[u]=c[u];
    29     L ret(dis[u]*c[u]);
    30     for(edge *i=pre[u];i;i=i->n){
    31         int e(i->e);
    32         if(e==fa)continue;
    33         dis[e]=dis[u]+i->w;
    34         ret+=dfs(e,u);
    35         size[u]+=size[e];
    36     }
    37     return ret;
    38 }
    39 inline void cal(int u,int fa){
    40     for(edge *i=pre[u];i;i=i->n){
    41         int e(i->e);
    42         if(e==fa)continue;
    43         if(sum<size[e]<<1){
    44             ans+=(sum-(size[e]<<1))*i->w;
    45             cal(e,u);
    46         }
    47     }
    48 }
    49 int main(){
    50     memset(pre,NULL,sizeof(pre));
    51     n=read();
    52     for(int i=1;i<=n;++i)
    53         c[i]=read();
    54     for(int i=1;i<n;++i){
    55         int x(read()),y(read()),z(read());
    56         insert(x,y,z),insert(y,x,z);
    57     }
    58     ans=dfs(1,0);
    59     sum=size[1];
    60     cal(1,0);
    61     printf("%lld",ans);
    62 }
    View Code
  • 相关阅读:
    [转]AsyncTask的用法
    [转]Android Service学习之本地服务
    强制页面运行于IE8模式下
    标签分类
    获取元素的文本
    遍历节点的API
    为IE的javascript提速
    我的选择器 获得经过标记的没有重复的tagName等于tag的元素集
    kangax 的javascript谜题
    自动执行函数
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7640540.html
Copyright © 2020-2023  润新知