2-SAT 學習筆記

June_Failure發表於2024-04-06

2-SAT 學習筆記

P4782 【模板】2-SAT

2-SAT 問題模型:構造 bool 變數 \(x_1,x_2...x_n\),使得滿足一些限制一對 \(x_1\)\(x_2\) 取值的條件合法。

很顯然根據 Floyd 傳遞閉包可以做到 \(O(n^3+m)\),但不太行。

\(O(n+m)\) 的做法,發現對於每個條件是要我們選擇一種取值(選擇就很縹緲),我們考慮轉換為一些定性的限制條件(更為直接一些)。

因為每個點只有兩種取值,所以對每個限制考慮分類討論,拿 \(x_7\) 為假或 \(x_2\) 為假舉例。

如果 \(x_7\) 取假,那麼對 \(x_2\) 沒有限制。如果 \(x_7\) 取真,那麼 \(x_2\)必須取假。所以把他轉換到圖論模型,對 \(x_2\)\(¬x_7\) 連邊。同理,對 \(x_7\)\(¬x_2\) 連邊,邊的含義就是如果取了 \(u\),那就必須取 \(v\)

考慮無解的情況,很顯然,如果一個 \(x_i\) 我們欽定它是 \(1\),但是發現推了一圈回來以後發現是 \(0\),那就產生了矛盾,那說明 \(x_i=1\) 是不可取的。

回到我們建出來的圖上,實際就是如果 \(x_i\) 可以走到 \(¬x_i\)\(¬x_i\) 能走到 \(x_i\) 那就是無解。

容易發現,他們是在一個強連通分量裡面的,因為他們可以互相抵達。

所以我們只用對建出來的圖跑一個縮點即可,如果 \(x_i\)\(¬x_i\) 在一個強連通分量裡面,那必然無解。

那考慮有解的情況的構造。

縮完了點以後,我們發現,拓撲序小的點一定是可以一層一層往裡面推出來拓撲序大的點的答案,反之不行。

原因是如果你選擇了拓撲序大的話,拓撲序小的點所在的那個環,其實就不能被更新到了。

但是 Tarjan 搞出來的拓撲序恰好的倒序的,因為他是個 dfs,是自下而上的找到 SCC,所以標號大的才是拓撲序小的點。

具體實現是要開 \(2n\) 個點來表示 \(0/1\) 的取值。

如果是 \(a \oplus b\),那顯然是如果 \(a\) 取了 \(1\)\(b\) 只能取 \(0\),顯然 \(a\)\(¬b\) 連邊, \(b\)\(¬a\) 連邊。

如果是 $a \land b $,如果 \(a\) 取了 \(0\),必然矛盾,所以 \(¬a\)\(a\) 連邊直接讓他矛盾掉。

在實際問題裡面,可以轉換成一個點的選/不選成為 \(0/1\) 的變數,單獨對每個點和每個限制考慮,這是兩種不一樣的思路。