大致題意(有簡化)
給定一個 \(n\) 個點,\(m\) 條邊的 DAG,邊有邊權。
選出一棵根向生成森林。其中有 \(X\),\(Y\) 兩種權值:
- 選擇一條邊對 \(X\) 的貢獻為邊權;
- 對於 \(u\) 的第 \(i\) 個孩子,對 \(X\) 還有 \(n - i + 1\) 的貢獻;
- \(Y\) 定義為葉子個數。
最小化 \(\dfrac{X^k}{Y}\),其中 \(k \in \{1, 2\}\)。
做法
思路大致來自 \(n\) 次費用流限制 \(Y\) 值的討論。
構造最大費用流模型。
定義 \(\infty\) 是一個遠大於最短路長度的有限數。
- 將每個點拆為入點 \(u\)、出點\(u'\);
- \(S\) 向所有 \(u\) 連容量 \(1\) ,價值 \(-n\) 的邊,用於提供葉子的流量,且 \(S\) 無其他出邊;(這保證了 \(\operatorname{flow}(S) = Y\))
- 非葉子節點的流量由孩子提供;對於邊 \((u, v, w)\),連接 \(u' \to v\),容量 \(1\),價值 \(w\) 的邊;
- 每個點的入點和出點之間存在一條容量為 \(1\) 的邊,價值為 \(n + \infty\) (其中 \(+\infty\) 保證了由 \(S\) 的流量(葉子)構造的森林包含了每一個點;\(n\) 用於提供 \(u\) 的第一個孩子的貢獻,若 \(u\) 是葉子,則用 \(S \to u\) 的 \(-n\) 價值抵消)
- 對於 \(u\) 向 \(T\) (注意不是 \(u'\))依次連接容量為 \(1\),邊權依次為 \(n - 1, n - 2, \dots, 1\) 的邊,用於消除 \(1\) 個以上孩子的流量,以及計算貢獻;
- 對於 \(u'\) 向 \(T\) 連價值 \(0\) 的邊,若 \(u\) 為某棵樹的根,那么這條邊用於保證 \(u,u'\) 的邊存在 \(1\) 的流量,保證正確。
通過這個模型,我們可以准確控制當前 \(Y\) 值,且如果價值大於 \(n \times \infty\),那么可以保證構造出合法的森林。
因此只需要 \(n\) 次增廣來枚舉 \(Y\) 值即可計算出答案。
如果使用 Dijkstra 費用流,動態加入 \(n - 1, n - 2, \dots, 1\) 的邊,復雜度 \(\mathcal O(n(n + m) \log n)\)。