2-SAT 문제
각 변수가 참/거짓 둘 중 하나이고, 절(clause)이 모두 변수 두 개의 OR로 이뤄진
논리식이 있다. 이 식 전체를 참으로 만드는 변수 배정이 존재하는지, 있다면 하나를
구하는 문제가 2-SAT이다. 일반 SAT는 NP-완전이지만, 절이 2개의 리터럴로만
이뤄지면 다항 시간에 풀린다.
핵심: OR를 함의로
\((a \lor b)\)는 다음 두 함의와 논리적으로 동치다.
$$ (a \lor b) \equiv (\lnot a \to b) \land (\lnot b \to a) $$
"\(a\)가 거짓이면 \(b\)는 반드시 참이어야 한다"는 뜻이다. 모든 절을 이렇게 함의 쌍
으로 바꿔, 각 리터럴(변수 \(x\)와 그 부정 \(\lnot x\))을 정점으로 하는 함의
그래프(implication graph) 를 만든다. 정점은 변수당 2개라 총 \(2n\)개다.
SCC로 모순 판정
함의 그래프에서 \(a \to b\) 경로가 있으면 "\(a\)가 참이면 \(b\)도 참"이라는 강제
관계가 성립한다. 따라서 어떤 변수 \(x\)에 대해 \(x\)와 \(\lnot x\)가 같은 SCC에
속한다면, \(x \to \lnot x \to x\)가 되어 "\(x\)가 참이면 \(x\)가 거짓이고, 거짓이면
참"이라는 모순이 생긴다.
판정 정리: 모든 변수 \(x\)에 대해 \(x\)와 \(\lnot x\)가 서로 다른 SCC에 있으면,
그리고 오직 그럴 때만 만족 가능한 배정이 존재한다.
이 정리 덕분에 2-SAT은 SCC 한 번으로 해결된다.
값 배정: 위상 순서
해가 존재할 때 실제 배정은 SCC의 위상 순서로 정한다. 타잔으로 SCC를 구하면
SCC 번호가 위상 역순으로 매겨지는데, 이때 규칙은 간단하다.
변수 \(x\)에 대해, \(x\)가 속한 SCC의 위상 순서가 \(\lnot x\)의 SCC보다 뒤에
있으면 \(x = \text{참}\), 아니면 거짓.
타잔의 comp 번호로 말하면 comp[x] < comp[¬x]일 때 \(x\)를 참으로 둔다(타잔
번호가 위상 역순이므로). 이 배정이 모든 함의를 어기지 않음은, 함의 그래프가
대칭(스큐 대칭) 구조를 갖기 때문에 보장된다.
복잡도
함의 그래프의 정점은 \(2n\)개, 간선은 절 하나당 2개이므로 \(2m\)개다. SCC가
\(O(V + E) = O(n + m)\)이므로 2-SAT 전체가 선형 시간에 끝난다.