传送门
题意
有一棵 n n n 个节点的以 s s s 为根的树。每条树边都有一个长度。每次操作可以把一条树边的长度加 1 1 1 。
问:至少操作多少次,可以使根节点到每个叶子节点的距离相等。
结论 1 1 1
对于任意子树,其根节点到其每个叶子节点的距离相等。
证明 :
反证法。
设对于根为 R R R 的树的根为 r r r 的某一子树,有两个叶子 a a a 、b b b 到 r r r 的距离不等。
那么不妨设节点 x x x 与 y y y 间的距离为 d i s ( x , y ) dis(x,y) d i s ( x , y ) ,则有
d i s ( a , r ) ≠ d i s ( b , r ) dis(a,r)\not=dis(b,r)
d i s ( a , r ) = d i s ( b , r )
所以
d i s ( a , r ) + d i s ( r , R ) ≠ d i s ( b , r ) + d i s ( r , R ) dis(a,r)+dis(r,R)\not=dis(b,r)+dis(r,R)
d i s ( a , r ) + d i s ( r , R ) = d i s ( b , r ) + d i s ( r , R )
得
d i s ( a , R ) ≠ d i s ( b , R ) dis(a,R)\not=dis(b,R)
d i s ( a , R ) = d i s ( b , R )
即 a a a 、b b b 到 R R R 的距离不等。这与题目条件矛盾,所以命题成立。
解法
既然结论 1 1 1 成立,那么先从最简单的情况入手。
如图,在这一棵以 1 1 1 为根的树中,在操作后,根节点 1 1 1 到叶子的距离最小是几?
很明显的,这个值应该是所有叶子到根的所有距离的最大值。
那么对于每个节点都实行此原则,就结束了。
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <bits/stdc++.h> using namespace std;using uint = unsigned ;using ll = long long ;using ull = unsigned long long ;using pii = pair<int ,int >;using pll = pair<ll,ll>;#define int ll int hd[500005 <<1 ],nxt[500005 <<1 ],to[500005 <<1 ],we[500005 <<1 ],et=0 ;inline void adde (int u,int v,int w) { ++et,to[et]=v,we[et]=w,nxt[et]=hd[u],hd[u]=et; }int n,s,ans,dp[500005 ];void dfs (int u,int fa) { int mx=0 ,tot=0 ; for (int i=hd[u],v,t; v=to[i],t=we[i],i; i=nxt[i]) { if (v==fa) continue ; dfs (v,u); if (dp[v]+t>mx) { ans+=(dp[v]+t-mx)*tot; mx=dp[v]+t; } else ans+=(mx-dp[v]-t); ++tot; } dp[u]=mx; }signed main () { cin>>n>>s; for (int i=1 ; i<n; ++i) { int u,v,t; cin>>u>>v>>t; adde (u,v,t); adde (v,u,t); } dfs (s,0 ); cout<<ans<<endl; }