有一棵包含n個節點和n-1條邊的樹,規定樹鏈(u,v)為樹上從u到v的簡單路徑。
樹的每條邊上都有乙個正整數,這個正整數被稱作這條邊的顏色,規定一條樹鏈的權值w(u,v)為這條樹鏈上所有邊的顏色的代數和。
而整棵樹的權值為所有不同的樹鏈的權值的代數和。
已知所有邊的顏色集合恰好為1到n-1這n-1個不同的正整數,請你為每條邊安排一種顏色,使得這棵樹的權值盡量小,你不需要給出具體方案,只需要求出這個最小的權值即可。
測試資料第一行,是乙個正整數n(1≤n≤1e5),表示樹的節點個數接下來n-1行,每行兩個用空格隔開的整數u,v,表示樹上有一條邊連線u和v
乙個整數,表示了這棵樹的最小的權值。示例1
複製
4複製1 22 3
3 4
19
w(1,2)+w(1,3)+w(1,4)+w(2,3)+w(2,4)+w(3,4)=3+4+6+1+3+2=19首先如果要找最小的話,肯定讓經過邊次數最多的那條邊權值最小,經過邊次數最小的那條邊權值最大
就是先dfs找出這個點孩子節點個數,就是讓sz[i]*(n-sz[i])就是這個邊的用的次數,然後排個序就行
#include#includeusing
namespace
std;
typedef
long
long
ll;const
int maxn=1e5+100
;ll sz[maxn];
//子樹的大小
//子數的大小乘(n-sz[i])就是這個邊的經過次數
vectorv[maxn];
void dfs(int u,int
fa) dfs(p,u);
sz[u]+=sz[p];
}}int
main()
dfs(
1,-1
);
for(int i=2;i<=n;i++)
sort(sz+2,sz+n+1
); ll ans=0
;
for(int i=2;i<=n;i++)
cout
}
樹上求和( dfs序 線段樹 )
題目鏈結 解題報告 將樹轉化成dfs序,對於任意節點及其子樹總是一段連續的區間,那麼轉化成區間問題。ai b 2 ai ai 2 ai b b b 很明顯線段樹維護即可。define first f define second s define ll long long define mp make...
nefu 1330 樹上求和dfs序 線段樹
dfs序即先序遍歷樹,對於第乙個節點進行總結點個數加一並且賦值操作。思路 對於給出的點,進行vecter建樹。建樹完成後dfs序求出各節點,dfs序,ls i 表示當前節點的dfs序為多少,rs i 表示以當前節點為根的子樹的最右邊節點值。include include include includ...
D 樹上求和
這道題直接用了樹鏈剖分的板子 套上模板之後,需要注意的就是平方和的求法 1 include2 include3 include4 include5 include6 define rint register int 7 define mem a,b memset a,b sizeof a 8 def...