肥宅快樂樹是一棵神秘而巨大的樹,它長有許多枝條和節點,每條枝連線樹中兩個節點,每個節點上都長有一瓶肥宅快樂水。 何老闆是肥宅快樂水的資深愛好者。歷經艱難,他終於找到了這棵傳說中的快樂樹。他想要獲取樹上所有的快樂水,迫不及待地想從樹根往樹上爬。 每經過一條樹枝都會耗費一定體力。而且快樂樹自帶防禦功能,即每條枝上都有乙個一次性陷阱,一旦踏上該枝,何老闆就會被立即彈射回地面,他得重新從根往上爬。 (注1:一次性陷阱是指,陷阱只在第一次經過該枝時有效) (注2:從i號點回到i的父親節點,不耗費體力) 每個節點上都有開有一些肥宅快樂花,花的香氣可以讓何老闆經過當前節點所連的樹枝時,耗費的體力值減少。不同節點的快樂花數量不一,產生的減少體力消耗的效果也不一定相同。 何老闆發現快樂樹還有乙個神秘「換根」功能。何老闆可以將指定節點變換為樹根,變換後,樹中樹枝連線情況保持不變。但是只能進行一次換根操作。 快樂樹共n個節點,編號1到n,開始時1號點為根。 何老闆想知道,以哪個節點為根才能使他收集齊n瓶快樂水耗費的總體力最少。請你幫你計算。
解發現每條邊都經過兒子節點的size值
換根的話只有一條邊的貢獻改變
考慮換根的話 可以dfs 也可以樹形dp 以子樹為狀態
code:
#include#includeusing namespace std;
#define maxnn 1000010
#define ll long long
int n;
ll las[maxnn],en[maxnn],le[maxnn],tot,nex[maxnn];
ll size[maxnn],w[maxnn];
int mark[maxnn];
ll ans=0;
ll root=1;
ll cnt=0;
ll aass=0;
ll pos=0;
void add(int a,int b,ll c)
void dfs1(int v,int fa)
} } void dfs2(int v,int fa)
} } void huan(int v,int fa)
huan(u,v);
ans=ans+le[i]*t***-t****w[v]-(tmp2-t***)*(le[i]-w[u]);
size[v]=tmp2;
size[u]=t***;
} }
} int main()
for(int i=1;idfs1(1,1);
pos=1;
dfs2(1,1);
aass=ans;mark[1]=1;
huan(root,root);
cout
樹形 dp 換根 dp
樹形dp 樹形動歸一般是依賴於dfs的,根據動歸的後效性,父節點的狀態一般都依賴子節點的狀態以某種方式轉移而來 換根的p2015 設f i j 表示i的子樹上保留j條邊最多蘋果數 p2279 狀態表示f x 0 覆蓋到x的爺爺和x整棵子樹 向上2層 最少個數 f x 1 覆蓋到x的父親和x子樹 向上...
樹形DP 換根DP
某些樹形dp問題中,我們要求的值是類似 以當前節點為根節點得到的答案 卻沒有給出固定的根節點,若仍然按照常規的樹形dp思路對每個點進行dp,我們對每乙個節點均進行一次 dfs 最後的複雜度是 o left n 2 right 如果我們先假設任意乙個點為根進行 dp,求出當前樹形結構下以每個點為根的子...
辭樹的肥宅快樂水
題目描述 又到了基情四射的夏天,大家出去約妹子,而肥宅辭樹只想宅在機房喝肥宅快樂水。辭樹一下 子買了n瓶肥宅快樂水。已知他一天裡至少喝掉一瓶肥宅水且他是一口乾掉一整瓶。肥宅orz 他想要知道自己一共有多少種喝肥宅水的方案。兩種方案被認為是不同的,當且僅當辭樹買的 這些肥宅水能喝的天數不同,或者存在一...