题目描述
在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路。 每条道路的修建都要付出一定的费用,这个费用等于道路长度乘以道路两端 的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4 个国家,如果该道路长度为 1,则费用为 1×|2 – 4|=2。图中圆圈里的数字表示国 家的编号。
由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建 费用难以用人工计算,国王们决定找人设计一个软件,对于给定的建造方案,计 算出所需要的费用。请你帮助国王们设计一个这样的软件。
输入输出格式
输入格式:
输入的第一行包含一个整数 n,表示 W 星球上的国家的数量,国家从 1 到 n 编号。 接下来 n – 1 行描述道路建设情况,其中第 i 行包含三个整数 ai、bi和 ci,表 示第 i 条双向道路修建在 ai与 bi两个国家之间,长度为 ci。
输出格式:
输出一个整数,表示修建所有道路所需要的总费用。
输入输出样例
说明
1≤ai, bi≤n
0≤ci≤10^6
2≤n≤10^6
‘
解题思路:
很明显这是一棵树,可以预处理处每个节点的size(大小)
那么就可以枚举每条边,边(u,v) dep[u]<dep[v]
对于这条边来说,两边的点的个数分别为
size[v] 和 size[1]-size[v]
注意LL问题
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #define ll long long 6 #include<cstring> 7 #include<string> 8 #define DB double 9 using namespace std; 10 const int N=2000010; 11 struct node{ 12 int u,v,c,ne; 13 }e[N]; 14 int h[N],tot,n; 15 void add(int u,int v,int c) 16 { 17 tot++;e[tot]=(node){u,v,c,h[u]};h[u]=tot; 18 } 19 int dep[N],f[N],size[N]; 20 void dfs(int u) 21 { 22 size[u]=1; 23 for(int i=h[u];i;i=e[i].ne) 24 { 25 int rr=e[i].v; 26 if(dep[rr]==0) 27 { 28 dep[rr]=dep[u]+1;f[rr]=u; 29 dfs(rr); 30 size[u]+=size[rr]; 31 } 32 } 33 } 34 ll ans; 35 int main() 36 { 37 scanf("%d",&n); 38 for(int i=1,x,y,z;i<=n-1;++i) 39 { 40 scanf("%d%d%d",&x,&y,&z); 41 add(x,y,z);add(y,x,z); 42 } 43 dep[1]=1; 44 dfs(1); 45 for(int i=1;i<=tot;i+=2) 46 { 47 int u=e[i].u,v=e[i].v; 48 if(dep[u]>dep[v]) swap(u,v); 49 int l=size[v],r=(size[1]-size[v]); 50 ans+=(ll)e[i].c*abs(l-r); 51 } 52 printf("%lld",ans); 53 return 0; 54 }
势力分华,不近者为洁,近之而不染者尤洁。