您的位置:首页 > 其它

【bzoj1827/Usaco2010 Mar】gather 奶牛大集会——树的重心+贪心

2017-09-20 14:16 288 查看

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号没有奶牛居住。
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long LL;
const int N=1e5+10;
struct node{
int ne,to;LL w;
}e[N*2];
int tot=0,n,first
,C
;
LL dis
,sz
;
int read(){
int ans=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
return ans*f;
}
/*-----------------------------------------------------*/
LL ans=0;
void add(int u,int v,LL w){
e[++tot]=(node){first[u],v,w};first[u]=tot;
e[++tot]=(node){first[v],u,w};first[v]=tot;
}
LL dfs(int x,int fa){
sz[x]=C[x];LL sum=dis[x]*C[x];
for(int i=first[x];i;i=e[i].ne){
int to=e[i].to;if(to==fa)continue;
dis[to]=dis[x]+e[i].w;
sum+=dfs(to,x);
sz[x]+=sz[to];
}
return sum;
}
void move(int x,int fa){
for(int i=first[x];i;i=e[i].ne){
int to=e[i].to;
if(to!=fa&&sz[1]<2*sz[to]){
ans+=(sz[1]-2*sz[to])*e[i].w;
move(to,x);return;
}
}
}
int main(){
n=read();
for(int i=1;i<=n;i++)C[i]=read();
for(int i=1,ai,bi;i<=n-1;i++){
ai=read();bi=read();LL ci=read();add(ai,bi,ci);
}
ans=dfs(1,0);
move(1,0);
printf("%lld\n",ans);
return 0;
}
bzoj1827

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: