1+ //! A 2-SAT Solver.
12use crate :: internal_scc;
23
4+ /// A 2-SAT Solver.
5+ ///
6+ /// For variables $x_0, x_1, \ldots, x_{N - 1}$ and clauses with from
7+ ///
8+ /// \\[
9+ /// (x_i = f) \lor (x_j = g)
10+ /// \\]
11+ ///
12+ /// it decides whether there is a truth assignment that satisfies all clauses.
13+ ///
14+ /// # Example
15+ ///
16+ /// ```
17+ /// #![allow(clippy::many_single_char_names)]
18+ ///
19+ /// use ac_library_rs::TwoSat;
20+ /// use proconio::{input, marker::Bytes, source::once::OnceSource};
21+ ///
22+ /// input! {
23+ /// from OnceSource::from(
24+ /// "3\n\
25+ /// 3\n\
26+ /// a b\n\
27+ /// !b c\n\
28+ /// !a !a\n",
29+ /// ),
30+ /// n: usize,
31+ /// pqs: [(Bytes, Bytes)],
32+ /// }
33+ ///
34+ /// let mut twosat = TwoSat::new(n);
35+ ///
36+ /// for (p, q) in pqs {
37+ /// fn parse(s: &[u8]) -> (usize, bool) {
38+ /// match *s {
39+ /// [c] => ((c - b'a').into(), true),
40+ /// [b'!', c] => ((c - b'a').into(), false),
41+ /// _ => unreachable!(),
42+ /// }
43+ /// }
44+ /// let ((i, f), (j, g)) = (parse(&p), parse(&q));
45+ /// twosat.add_clause(i, f, j, g);
46+ /// }
47+ ///
48+ /// assert!(twosat.satisfiable());
49+ /// assert_eq!(twosat.answer(), [false, true, true]);
50+ /// ```
351pub struct TwoSat {
452 n : usize ,
553 scc : internal_scc:: SccGraph ,
654 answer : Vec < bool > ,
755}
856impl TwoSat {
57+ /// Creates a new `TwoSat` of `n` variables and 0 clauses.
58+ ///
59+ /// # Constraints
60+ ///
61+ /// - $0 \leq n \leq 10^8$
62+ ///
63+ /// # Complexity
64+ ///
65+ /// - $O(n)$
966 pub fn new ( n : usize ) -> Self {
1067 TwoSat {
1168 n,
1269 answer : vec ! [ false ; n] ,
1370 scc : internal_scc:: SccGraph :: new ( 2 * n) ,
1471 }
1572 }
73+ /// Adds a clause $(x_i = f) \lor (x_j = g)$.
74+ ///
75+ /// # Constraints
76+ ///
77+ /// - $0 \leq i < n$
78+ /// - $0 \leq j < n$
79+ ///
80+ /// # Panics
81+ ///
82+ /// Panics if the above constraints are not satisfied.
83+ ///
84+ /// # Complexity
85+ ///
86+ /// - $O(1)$ amortized
1687 pub fn add_clause ( & mut self , i : usize , f : bool , j : usize , g : bool ) {
1788 assert ! ( i < self . n && j < self . n) ;
1889 self . scc . add_edge ( 2 * i + !f as usize , 2 * j + g as usize ) ;
1990 self . scc . add_edge ( 2 * j + !g as usize , 2 * i + f as usize ) ;
2091 }
92+ /// Returns whether there is a truth assignment that satisfies all clauses.
93+ ///
94+ /// # Complexity
95+ ///
96+ /// - $O(n + m)$ where $m$ is the number of added clauses
2197 pub fn satisfiable ( & mut self ) -> bool {
2298 let id = self . scc . scc_ids ( ) . 1 ;
2399 for i in 0 ..self . n {
@@ -28,6 +104,17 @@ impl TwoSat {
28104 }
29105 true
30106 }
107+ /// Returns a truth assignment that satisfies all clauses **of the last call of [`satisfiable`]**.
108+ ///
109+ /// # Constraints
110+ ///
111+ /// - [`satisfiable`] is called after adding all clauses and it has returned `true`.
112+ ///
113+ /// # Complexity
114+ ///
115+ /// - $O(n)$
116+ ///
117+ /// [`satisfiable`]: #method.satisfiable
31118 pub fn answer ( & self ) -> & [ bool ] {
32119 & self . answer
33120 }
0 commit comments