考慮 \(\tt DP\),朴素的想法是令 \(f_S\) 表示 \(S\) 這個導出子圖將邊定向集合構成 \(\tt DAG\) 的方案數。
轉移可以考慮剝去所有入度為 \(0\) 的點,那么我們就需要得到僅存在 \(T\) 這個子集為 \(S\) 中入度為 \(0\) 的點的方法。
直接做是困難的,考慮容斥。
強制欽定 \(T\) 這個子集為 \(S\) 中入度為 \(0\) 的點,其他的點不管,\(T \rightarrow S - T\) 的邊顯然可以連或不連,而 \(S - T \rightarrow T\) 中間的邊必須強制不連,這樣可以得到轉移:
令 \(q_T = 2 ^ {ways(T, S - T)} \times f_{S - T}\),令 \(S\) 中恰好僅有 \(T\) 做為入度為 \(0\) 的點的方案為 \(p_T\),那么有:
根據二項式反演的集合形式,有:
在本題中,我們需要求:
因此有 \(f\) 的轉移:
此時只要處理出 \(ways(T, S - T)\) 即可做到 \(\mathcal{O}(3 ^ n)\)。
對於每個 \(S\),我們考慮單獨計算 \(ways(T, S - T)(T \subseteq S)\),將其簡寫為 \(w_T\)。
對 \(w_T\) 進行 \(\tt DP\),顯然每次只需取出一個在 \(T\) 中的點進行轉移即可,可以使用 \(\mathtt{lowbit}, \mathcal{O}(1)\) 取出。
轉移只需預處理出 \(w1_{i, S}, w2_{i, S}\) 分別表示 \(i \rightarrow S\) 中的邊數和 \(S \rightarrow i\) 中的邊數即可,這部分直接暴力。
於是本題可以做到時間復雜度 \(\mathcal{O}(3 ^ n)\),空間復雜度 \(\mathcal{O}(n \times 2 ^ n)\)。
