牛客 3566B 小琛和他的學校 樹形dp

2021-10-01 18:42:02 字數 1312 閱讀 3099

小琛是一所學校的校長。

他的學校有n個校區(編號1~n),被n-1條雙向道路連線,呈樹形結構。

第i個校區共有ai個學生。

第i天早上,所有的學生會沿最短路走到第i個校區參加活動,晚上再原路返回。

乙個人通過第j條通道一次(即一人次),需要小琛支付wj的維護費用。

小琛想知道第n天結束之後,對於每一條通道,他總共需要支付多少費用。

對於100%的資料,1≤ n ≤ 200,000,1≤ a[i]≤ 10,000,1≤ w[i] ≤ 10,000。

第一行乙個整數n,表示校區的數量。

接下來一行,n個整數,表示a1~an。

第3到第n+1行,每行包含3個整數。第i行包含三個整數ui-2,vi-2,wi-2,表示第i-2條通道所連線的兩個校區的編號,以及一人次通過這條通道的費用。

共n-1行,每行乙個整數。

第i行的整數表示小琛對於第i條通道所需支付的費用。

4

2 1 2 3

1 3 1

1 2 3

4 1 2

24

6056

樹形dp。dfs返回子樹的人數和點數。

路(a,b)的費用=(子樹a的人數*子樹b的點數+子樹a的點數*子樹b的人數)*2

#include

#include

using namespace std;

typedef

long

long ll;

const

int n=

2e5+20;

int n,a[n]

,head[n]

,cs;

ll pep,ans[n]

;struct nodeside[n<<1]

;struct node

node

(ll x,ll y)};

void

add(

int x,

int y,

int v)

node dfs

(int x,

int fa)

return re;

}int

main()

for(

int i=

1;i)dfs(1

,-1)

;int en=n-1;

for(

int i=

0;i)printf

("%lld\n"

,ans[i]);

return0;

}

牛客練習賽56 B 小琛和他的學校

思路 一條路可把圖分為左右兩部分。l ci,l peo,r ci,r peo,w 分別為左邊城市數和人數,右邊城市數和人數,該路的費用。我們知道,左邊的人要去右邊的r ci個城市,右邊的人要去左邊的l ci個城市,那麼該路的費用就是 cost 2 w l ci r peo r ci l peo 注意...

牛客練習賽56 小魂和他的數列

題目鏈結 給出乙個數列,讓求長度為k的嚴格遞增子串行有多少個 怎麼做呢?顯然dp 這個是很好想的 for int i 1 i n i for int i 2 i m i 這個dp顯然tle 所以 當時沒有做出來。做到這裡不會做了。想不到怎麼優化。顯然在最裡面的那個迴圈的作用是字首和 小於a i 的位...

小A與尤拉路(牛客 樹的直徑)

題解 尤拉路 從圖中任意乙個點開始到圖中任意乙個點結束的路徑,並且圖中每條邊只通過恰好一次 問你走完這樹上所有的點最短路徑是什麼。因為樹是沒有環的,所以你走到葉子結點的時候需要往回走,也就是再走一遍剛剛走過的路。所以我們確定一條主道路,遇到分支就走一遍 主道路是不需要走兩遍的 因為所有長度都是已知的...