刷題 BZOJ 3252 攻略

2022-05-25 10:54:11 字數 1833 閱讀 4761

題目簡述:樹版[k取方格數]

眾所周知,桂木桂馬是攻略之神,開啟攻略之神模式後,他可以同時攻略k部遊戲。今天他得到了一款新遊戲《xx

半島》,這款遊戲有n個場景(scene),某些場景可以通過不同的選擇支到達其他場景。所有場景和選擇支構成樹狀

結構:開始遊戲時在根節點(共通線),葉子節點為結局。每個場景有乙個價值,現在桂馬開啟攻略之神模式,同

時攻略k次該遊戲,問他觀賞到的場景的價值和最大是多少(同一場景**多次是不能重複得到價值的)

「為什麼你還沒玩就知道每個場景的價值呢?」

「我已經看到結局了。」

第一行兩個正整數n,k

第二行n個正整數,表示每個場景的價值

以下n-1行,每行2個整數a,b,表示a場景有個選擇支通向b場景(即a是b的父親)

保證場景1為根節點

n<=200000,1<=場景價值<=2^31-1

輸出乙個整數表示答案

5 24 3 2 1 1

1 21 5

2 32 4

考慮貪心,我們需要找滿足以下條件的 \(k\) 條路徑:

路徑與路徑之間沒有重疊(以不重複計算貢獻);每條路徑的終點一定是葉子;每條路徑要可以直接或間接地到達根(即通過其它路徑)

然後答案要最大,那麼就是要找權值和最大的 \(k\) 條路徑

會發現,這些東西極其地類似於長鏈剖分。我們如果按照權值進行長鏈剖分,可以最優地將樹分割成滿足條件的乙個個路徑,取最大的 \(k\) 個即可

大概證明一下,首先長鏈剖分,每條鏈都是到達葉子節點的,並且肯定不會重複;然後因為是按照權值來剖分的,所以如果最終我們選了乙個起點不是根的鏈,那麼它的的起點的父親所在的鏈一定被選了,因為它們是重鏈和輕鏈的關係

#include#define ui unsigned int

#define ll long long

#define db double

#define ld long double

#define ull unsigned long long

#define rep(a,b,c) for(register int a=b,a##end=c;a<=a##end;++a)

#define dep(a,b,c) for(register int a=b,a##end=c;a>=a##end;--a)

const int maxn=200000+10;

int n,k,e,beg[maxn],nex[maxn],to[maxn],val[maxn],top[maxn],hson[maxn];

ll sum[maxn],mx[maxn],ans;

std::priority_queueq;

templateinline void read(t &x)

templateinline void write(t x,char ch='\0')

templateinline void chkmin(t &x,t y)

templateinline t min(t x,t y)

inline void insert(int x,int y)

inline void dfs1(int x,int f)

mx[x]+=val[x];

}inline void dfs2(int x,int tp)

inline void dfs(int x)

int main()

dfs1(1,0);dfs2(1,1);dfs(1);

while(!q.empty()&&k--)ans+=q.top(),q.pop();

write(ans,'\n');

return 0;

}

BZOJ 3252 攻略 思路題

傳送門 比較好想的一道思路題,結果有個地方沒開 long long wa 了三次。其實就是模仿一下樹鏈剖分,重新定義重兒子,乙個點的重兒子為所有兒子中到葉節點權值最大的點,然後就和樹鏈剖分一樣 dfs 一遍,把那些鏈的頂端的 sum 值放到乙個陣列排個序。include include includ...

BZOJ3252 攻略 可並堆

網上有很多人說用dfs序 線段樹做.其實stl的堆可以.可並堆可以.很多奇奇怪怪的東西都能做.可並堆比較好想.也比較好寫.分析 首先,這是乙個網路流做不了的題.資料太大.其次.我們可以這樣考慮一下,這個點的子樹中,將這個點的權值僅更新給最大的那個就能滿足 之後,在每乙個葉子節點上,建立乙個大根堆,d...

BZOJ 3252攻略 dfs序 線段樹

bzoj 3252 攻略 dfs序 線段樹 題目大意 給定一棵以1為根的n個點的樹,樹有點權且點權為正整數,可以選擇k條以根作為起點的路徑,每條路徑的價值即這條路徑上所有點的點權之和。但是選擇一條路徑之後,這條路徑上的所有點的點權會變成0。也就是說,這k條路徑中被重複選擇的點,其點權只能被計算一次 ...