[複習] 種類並查集
種類並查集也可叫做擴充套件域並查集。
前言
自從兩年多前剛學並查集時過了食物鏈後,就再也沒有寫過種類並查集。
今天回顧一下。
例題 1 食物鏈
P2024 [NOI2001] 食物鏈。
題目大意:有 \(n\) 個動物,每個動物屬於 \(A,B,C\) 種中的一種,\(A\) 吃 \(B\),\(B\) 吃 \(C\),\(C\) 吃 \(A\)。每次給出 \(x,y\) 同類或 \(x\) 吃 \(y\) 的資訊,看是否合法。
首先 \(x,y\) 同類可以想到用並查集維護。那麼 \(x\) 吃 \(y\) 怎麼維護呢。
當 \(x\) 吃 \(y\) 時,我們不能將 \(x,y\) 放到一個並查集裡表示它們不同。否則如果 \(a\to b,b\to c,c\to d\),那此時 \(a,d\) 其實是同類的。
考慮一個動物,我們並不需實際區分它是哪個類別,只需考慮它和其他動物的關係即可。
於是考慮並查集取出 \(3n\) 個點,\(1\sim n\) 為第一類,\(n+1\sim 2n\) 為第二類,\(2n+1\sim 3n\) 為第三類。
我們這樣表示它們的關係:
對於同一類中的點 \((x,y)\),如果它們在同一個集合中,則 \((x,y)\) 同類。
對於不在同一類中的點 \((x+kn,y+k'n)\),如果它們在同一個集合中,則 \((x,y)\) 不同類。
第一類吃第二類,第二類吃第三類,第三類吃第一類。
於是縮點就變成了:
- 如果 \(x,y\) 同類,那麼 \((x,y),(x+n,y+n),(x+2n,y+2n)\) 縮點。
- 如果 \(x\to y\),那麼 \((x,y+n),(x+n,y+2n),(x+2n,y)\) 縮點。
2-XOR-SAT
SAT 問題,是一個 NP 完全問題,求 \(n\) 個布林變數,有若干條限制,每條限制形如給定若干布林變數分別為 \(0/1\),要至少有一個布林變數滿足。
- 2-SAT 問題,每條限制由兩個變數組成,可以用 SCC 縮點在 \(O(n+m)\) 解決。
- XOR-SAT 問題,將 SAT 問題的限制改為用異或連線,每條限制要使最終異或值為 \(0/1\),可以用高斯消元在 \(O(n^3)\) 解決。
- 2-XOR-SAT 問題,每條限制給定兩個變數和它們的異或值,要求構造方案或判斷無解。
2-XOR-SAT 問題可用本篇的種類並查集做。
還是 \(1\sim n\) 表示第一類,\(n+1\sim 2n\) 表示第二類,同類點縮在一起表示它們相等,不同類點縮在一起表示它們不等。
我們知道,異或值指示了兩個布林數是否相同。
於是顯然有這樣的縮點策略:
- 如果 \(a_x\oplus a_y=1\),那麼縮點 \((x,y+n),(x+n,y)\) 表示 \((x,y)\) 不等。
- 如果 \(a_x\oplus a_y=0\),那麼縮點 \((x,y),(x+n,y+n)\) 表示 \((x,y)\) 相等。
例題 2 arc183_c
arc183_c。
題目大意:
有 \(n\) 個人,每個人是誠實或撒謊,清醒或糊塗。其中:
清醒的誠實人說真話。
清醒的撒謊人說假話。
糊塗的誠實人說假話。
糊塗的撒謊人說真話。
給定 \(m\) 個條件,形如 \(a,b\in [1,n],c=0/1\),表示 \(a\) 號人說 \(b\) 號人是誠實或撒謊。
我們可以設布林變數 \(p_i\) 為 \(0/1\) 表示 \(i\) 是誠實或是撒謊,\(q_i\) 為 \(0/1\) 表示 \(i\) 是清醒或是糊塗。
那麼條件 \((a,b,c)\) 就相當於要滿足 \(p_a\oplus q_a\oplus p_b=c\)。
這是三元的,並不好,我們可以考慮設 \(r_i=p_i\oplus q_i\),那麼條件就變成了 \(r_a\oplus p_b=c\),我們可以求 \(r_i,p_i\),然後用 \(q_i=r_i\oplus p_i\) 算出 \(q_i\)。
關於方案,如果最後合法了,那麼對於縮在一起的點(包括不同類點),我們指定一個點隨便取一個值後,就能全部確定這些點。