P2986 [USACO10MAR] great gathering cows
The center of gravity of the tree: find a point, the largest sub-tree nodes least all of its sub-tree, then the tree's center of gravity is the point, after deleting the center of gravity to produce more trees as balanced as possible
nature:
- Tree in the distance and all points of a point, and the distance to the center of gravity is minimal, if there are two distances and their distance and the same
- The two trees are connected by an edge, the center of gravity of the two trees original connection new center of gravity in the tree
- A tree add or delete a node, the center of gravity moves up the tree only one side position of
- The center of gravity of a tree has at most two, and adjacent
N can have points of view is divided into n node concluded to find the center of gravity!
And then seek the answer
#include<bits/stdc++.h> using namespace std; #define Max(x,y) (x)<(y)?(y):(x) #define Min(x,y) (x)<(y)?(x):(y) #define ll long long const int N=100000+5,M=1000000+5,inf=0x3f3f3f3f,P=9999973; int n,sum=0,a[N],size[N],mxs[N],dis[N]; int max_part=inf,zx; ll ans=0; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[N],tot=0; struct edge{int v,w,nxt;}e[N<<1]; void add(int u,int v,int w){ e[++tot]=(edge){v,w,head[u]},head[u]=tot; } void dfs(int u,int fa){ size[u]=a[u]; int maxsize=0; for(int i=head[u];i;i=e[i].nxt){ if(e[i].v==fa) continue; dfs(e[i].v,u); size[u]+=size[e[i].v]; maxsize=Max(maxsize,size[e[i].v]); } maxsize=Max(maxsize,sum-size[u]); if(maxsize<max_part) max_part=maxsize,zx=u; } void dfs2(int u,int fa){ for(int i=head[u];i;i=e[i].nxt) if(e[i].v!=fa) dis[e[i].v]=dis[u]+e[i].w,dfs2(e[i].v,u); } int main(){ freopen("in.txt","r",stdin); rd(n); for(int i=1;i<=n;++i) rd(a[i]),sum+=a[i]; for(int i=1,u,v,w;i<n;++i) rd(u),rd(v),rd(w),add(u,v,w),add(v,u,w); dfs(1,0); dis[zx]=0; dfs2(zx,0); for(int i=1;i<=n;++i) ans+=(ll)dis[i]*a[i]; printf("%lld",ans); return 0; }