[USACO10MAR] Great Cow Gathering G

[USACO10MAR] Great Cow Gathering G

题目描述

Bessie 正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。

每个奶牛居住在 N N N 个农场中的一个,这些农场由 N − 1 N-1 N1 条道路连接,并且从任意一个农场都能够到达另外一个农场。道路 i i i 连接农场 A i A_i Ai B i B_i Bi,长度为 L i L_i Li。集会可以在 N N N 个农场中的任意一个举行。另外,每个牛棚中居住着 C i C_i Ci 只奶牛。

在选择集会的地点的时候,Bessie 希望最大化方便的程度(也就是最小化不方便程度)。比如选择第 X X X 个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和(比如,农场 i i i 到达农场 X X X 的距离是 20 20 20,那么总路程就是 C i × 20 C_i\times 20 Ci×20)。帮助 Bessie 找出最方便的地点来举行大集会。

输入格式

第一行一个整数 N N N

第二到 N + 1 N+1 N+1 行:第 i + 1 i+1 i+1 行有一个整数 C i C_i Ci

N + 2 N+2 N+2 行到 2 N 2N 2N 行:第 i + N + 1 i+N+1 i+N+1 行为 3 3 3 个整数: A i , B i A_i,B_i Ai,Bi L i L_i Li

输出格式

一行一个整数,表示最小的不方便值。

样例 #1

样例输入 #1

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

样例输出 #1

15

提示

1 ≤ N ≤ 1 0 5 1\leq N\leq 10^5 1N105 1 ≤ A i ≤ B i ≤ N 1\leq A_i\leq B_i\leq N 1AiBiN 0 ≤ C i , L i ≤ 1 0 3 0 \leq C_i,L_i \leq 10^3 0Ci,Li103

思路

边带权点带权的一道 换根dp
是上一题STA-Station的ultra版

code

#include<bits/stdc++.h>
#define bl(i,a) for(long long i=head[a];i;i=nxt[i])
using namespace std;
const int N=2e6+3;

long long nxt[N],edge[N],head[N],dis[N],tot,n,c[N],sum,ans=1e17;
void add(int x,int y,int w){
    
    
	nxt[++tot]=head[x];
	head[x]=tot;
	edge[tot]=y;
	dis[tot]=w;
}

long long siz[N],f[N];
void getsiz(int me,int dad){
    
    
	siz[me]=c[me];
	bl(i,me){
    
    
		int v=edge[i];
		if(v==dad)continue;
		getsiz(v,me);
		siz[me]+=siz[v];
		f[me]=f[me]+f[v]+siz[v]*dis[i];
	}
}

long long d[N];
void dp(int me,int dad){
    
    
	bl(i,me){
    
    
		int v=edge[i];
		if(v==dad)continue;
		d[v]=1ll*d[me]-siz[v]*dis[i]+(sum-siz[v])*dis[i];
		ans=min(d[v],ans);
		dp(v,me);
	}
}

int main(){
    
    
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>c[i];sum+=c[i];
	}
	for(int i=1,l,r,w;i<n;i++){
    
    
		cin>>l>>r>>w;
		add(l,r,w);add(r,l,w);
	}
	getsiz(1,0);
	d[1]=f[1];
	dp(1,0);
	cout<<ans;
}

猜你喜欢

转载自blog.csdn.net/skyflying266/article/details/124911986