給定一顆樹,要求將其上的節點分成若干組,使得每一組的節點互相不擁有祖先-後代關係。定義每一組的值為該組節點權值最大值,求值總和最小值。
硬上不是很顯然的貪心,但是資料中鏈的情況給了提示。
考慮鏈的情況:
對於根節點兩側的鏈,我們分別排序,然後覆蓋選取即可。
這個貪心的正確性是顯然的。
現在考慮完整的資料:
對於每乙個節點,維護乙個大根堆,儲存選取的權值。然後從底向上啟發式合併,最後累加根節點的權值即可。
#include using namespace std;
namespace standardio
templateinline void write (t x)
}using namespace standardio;
namespace project edge[n<<1];
int tim;
int a[n],fa[n],dfn[n],tmp[n];
priority_queueq[n];
inline void add (int a,int b)
void dfs (int now)
for (register int j=1; j<=len; ++j) q[dfn[now]].push(tmp[j]);
} q[dfn[now]].push(a[now]); }
inline void main ()
dfs(1);
while (!q[dfn[1]].empty()) ans+=q[dfn[1]].top(),q[dfn[1]].pop();
write(ans); }
#undef int
}int main ()
十二省聯考2019 春節十二響
點這裡看題目。感覺自己好蠢 假如我們有兩棵樹 t 1,t 2 我們應該怎麼計算出它們合併之後的最優解呢?設最優情況下,t 1 的所有記憶體段的集合為 m 1 t 2 的集合為 m 2 我們可以知道,m 1,m 2 中所有的元素都是不能再合併的 廢話 考慮有 m 1,m 2 in m 1,m 1 m ...
P5290 十二省聯考2019 春節十二響
傳送門 考慮乙個子樹裡是怎麼劃分的,維護劃分出來的每個集合的最大值,這個可以用乙個 multiset 維護 設 s x 表示節點 x 的子樹中,最優劃分 劃分出來的每個塊的節點最大值 首先葉子節點的集合顯然只有它本身 然後考慮子樹之間的合併,設兩個子樹根節點為 x,y 因為兩個子樹之間一定不會有祖先...
P5290 十二省聯考2019 春節十二響
考試的時候,本來想拿60的貪心,但是只拿了15 很不開心!不過現在知道正解了qwq 對於每個點,都開乙個優先佇列,這個優先佇列裡的值,代表這個點的子樹分成的若干個集合中最大的值。那麼我們對於乙個沒有處理的點,分別列舉每乙個子樹,分別合併每乙個優先佇列,最後再加入這個點,得到新的優先佇列。對於正確性,...