前置:CTS2019D2T3
先進行一個轉化:初始認為樹上沒有邊,每個節點權值為 \(1\)。枚舉一個長度為 \((n-1)\) 的邊集排列,按照這個排列依次加入每條邊,加入一條邊時將這條邊所連接的兩個連通塊所有點的權值 \(\times \frac{1}{2}\)。
可以發現所有邊均加入后每個點的權值就是在這個邊集排列下成為最后節點的概率。
枚舉節點 \(root\) 計算它的答案,把 \(root\) 拉作整棵樹的根。
首先 \(root\) 和它的某個兒子之間的邊會讓 \(root\) 權值乘上 \(\frac{1}{2}\)。設該兒子是 \(v\),\((root,v)\) 加入時,\(v\) 會在某個連通塊 \(S\) 中。
此時對於邊集 \(\{(p,q)|p \in S \land q \in S\}\) 中的所有邊,它一定會在 \((root,v)\) 之前加入。
而對於邊集 \(\{(p,q)|p \in S \land q \not\in S\}\),這其中的每一條邊一定會在 \((root,v)\) 之后加入,且會對答案產生 \(\frac{1}{2}\) 的貢獻;而在 \((p,q)\) 加入的時候,\(q\) 節點又可能在某一個連通塊內,可以遞歸進入 \(q\) 的子樹考慮。
這樣考慮有兩個好處:第一個是可以找到邊之間加入順序的偏序關系,第二個是就有子問題的性質。
為了描述方便,設對於一個邊集排列會讓 \(root\) 所在連通塊變大的邊(即會讓權值乘上 \(\frac{1}{2}\) 的邊)稱為主動邊,反之稱為被動邊。加入一條主動邊時,可能會導致一些被動邊的產生(即上文中所提到的連通塊 \(S\) 中的邊)。
之前的思路是枚舉邊集排列算主被動邊,此時發現主被動邊思路優勢明顯,故考慮枚舉主動邊和主動邊產生的被動邊。
考慮一張新圖,新圖上的點與原樹上的邊一一對應,如果原樹上邊 \((u,v)\) 需要在邊 \((p,q)\) 之后加入則在新圖上從 \((u,v)\) 向 \((p,q)\) 連一條邊。故新圖上會有這樣一些邊:
- 一條主動邊向其產生的所有被動邊連邊;
- 一條主動邊向與其最近的主動邊祖先連邊(如果存在)。
此時有:新圖的所有拓撲序與所有滿足當前枚舉的主被動邊情況的序列的反序一一對應,原因是所有與主動被動邊相關的限制全部表現在了圖上,而拓撲序正好滿足所有偏序關系。
現在變成算拓撲序。注意到新圖是樹形圖,因為對於所有被動邊僅有產生它的主動邊向它連邊,而主動邊的導出子圖是一棵內向樹森林。內向樹或者外向樹的拓撲序易於計算,但它並不是內向樹或外向樹。
如果做了前置會很自然地想到進行容斥(麻煩做一下前置我這里就不細寫了 QAQ)。對主動邊與被動邊之間的邊容斥,那么新圖會變為內向森林,此時只需要考慮每個節點在新圖上的 \(size\)。
被動邊 \(size=1\) 無需考慮,而主動邊 \((u,v)\)(\(u\) 是 \(v\) 原樹上的父親)在新圖上的 \(size\) 可以發現等於 \(v\) 在原樹上的子樹大小減去原樹 \(v\) 的子樹中選擇不與主動邊連邊的被動邊數量。那么每條主動邊就只關心兒子里面被動邊的選擇情況了。
DP:設 \(f_{i,j}\) 表示原樹 \(i\) 節點子樹內有 \(j\) 條被動邊選擇不與主動邊連邊,\(i\) 節點內部的所有主動邊和被動邊的貢獻總和。
先考慮對於某一個狀態 \(f_{u,p}\) 如何轉移到父親上,設原樹上 \(u\) 節點子樹大小為 \(size_u\):
- \((i,u)\) 是主動邊,那么乘上計算拓撲序的貢獻 \(\frac{1}{size_u-p}\) 和選點概率 \(\frac{1}{2}\) 並轉移到 \(f_{i,p}\);
- \((i,u)\) 是被動邊且選擇不與主動邊連邊,那么乘上容斥系數 \(1\) 並轉移到 \(f_{i,p+1}\);
- \((i,u)\) 是被動邊且選擇與主動邊連邊,那么乘上容斥系數 \(-1\) 並轉移到 \(f_{i,p}\)。
對於多個子樹的合並顯然是樹形背包。答案是 \(\prod\limits_{(u,root) \in e} \sum\limits_{i=0}^{size_u-1} \frac{f_{u,i}}{2(size_u-i)}\),原因是 \(root\) 的所有兒子必須要是主動邊。
然后就做完了。單次的 DP 復雜度是 \(O(n^2)\) 的,故總復雜度為 \(O(n^3)\)。
吐槽:容斥主動邊和被動邊之間的邊要開 long double
,容斥主動邊和主動邊之間的邊開 double
就過了???