zoukankan      html  css  js  c++  java
  • 【bzoj1827/Usaco2010 Mar】gather 奶牛大集会——树的重心+贪心

    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
     

     
    钦定(?)1为这棵树的根。

    先dfs算出sz[x]表示x这棵子树的大小,dis[x]表示x到根的距离,易得sz[1]表示整棵树的大小。

    最开始ans为集会地点在1的总移动距离,设ans'为当前选择点的子节点选择后的总移动距离。

    那么:

    ans=anssz[to]∗e[i].w+(sz[1]sz[to]∗e[i].w;

    化简:

    ans=ans+(e[1]2sz[to]wi

    sz[1]2sz[to]<0时ans'<ans,说明子节点更优。

    sz[1]-2*sz[to]<0?这不就是树的重心吗?

    易知最优解即为在树的重心所取得。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 typedef long long LL;
     5 const int N=1e5+10;
     6 struct node{
     7     int ne,to;LL w;
     8 }e[N*2];
     9 int tot=0,n,first[N],C[N];
    10 LL dis[N],sz[N];
    11 int read(){
    12     int ans=0,f=1;char c=getchar();
    13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    14     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    15     return ans*f;
    16 }
    17 /*-----------------------------------------------------*/
    18 LL ans=0;
    19 void add(int u,int v,LL w){
    20     e[++tot]=(node){first[u],v,w};first[u]=tot;
    21     e[++tot]=(node){first[v],u,w};first[v]=tot;
    22 }
    23 LL dfs(int x,int fa){
    24     sz[x]=C[x];LL sum=dis[x]*C[x];
    25     for(int i=first[x];i;i=e[i].ne){
    26         int to=e[i].to;if(to==fa)continue;
    27         dis[to]=dis[x]+e[i].w;
    28         sum+=dfs(to,x);
    29         sz[x]+=sz[to];
    30     }
    31     return sum;
    32 }
    33 void move(int x,int fa){
    34     for(int i=first[x];i;i=e[i].ne){
    35         int to=e[i].to;
    36         if(to!=fa&&sz[1]<2*sz[to]){
    37             ans+=(sz[1]-2*sz[to])*e[i].w;
    38             move(to,x);return;
    39         }
    40     }
    41 }
    42 int main(){
    43     n=read();
    44     for(int i=1;i<=n;i++)C[i]=read();
    45     for(int i=1,ai,bi;i<=n-1;i++){
    46         ai=read();bi=read();LL ci=read();add(ai,bi,ci);    
    47     }
    48     ans=dfs(1,0);
    49     move(1,0);
    50     printf("%lld
    ",ans);
    51     return 0;
    52 }
    bzoj1827
  • 相关阅读:
    Django搭建环境
    python切片
    python数据类型
    jquery 淡入淡出属性
    Jquery Tab切换
    jQuery Clone方法
    jQuery属性操作
    python 变量以及循环
    获取网站目录
    posting-jsonobject-with-httpclient-from-web-api
  • 原文地址:https://www.cnblogs.com/JKAI/p/7561251.html
Copyright © 2011-2022 走看看