樹上求和(dfs

2022-06-08 17:45:10 字數 1223 閱讀 3635

有一棵包含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#include

using

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...