2-sat The problem is this: there are $n$ Boolean variable $x_i$, and another $m$ need to meet the conditions, each condition is in the form of "$x _i$ true/False or $x_j$ true/false". For example: "$x _1$ is True or $x_3$ is false". Note that the "or" here refers to two conditions at least one is correct, such as $x_1$ and $x_3$ altogether have $3$ in combination to meet "$x _1$ true or $x_3$ for false." The goal of the 2-SAT problem is to assign values to each variable so that all conditions are met. A common way to solve 2-sat problems is to construct a graph $g$, where each variable $x_i$ is split into two nodes $2i$ and $2i+1$, respectively, to indicate that $x_i$ is false and $x_i$ is true. Finally, select one of the node markers for each variable. For example, if the node $2i$ is marked, the $x_i$ is false, and if $2i+1$ is marked, $x_i$ is true. For the "$x _i$ false or $x_j$ for false" condition, we even have a forward edge $2i+1 \rightarrow 2j$, indicating that if the tag node $2i+1$ then also must mark nodes $j$, the same way also need to connect a forward edge $2j+1 \rightarrow 2i $ For other situations, you can also have a similar edge. In other words, each condition corresponds to two "symmetrical" edges. Next, consider each variable that is not assigned, set to $x_i$. We first assume that it is false, then mark the borrowing point $2_i$, and mark all the nodes that can be labeled along the forward edge. If two nodes corresponding to a variable are identified during the tagging process, the assumption "$x _i$ is False" is not true, and needs to be changed to "$x _i$ is True" and then re-tagged. Note that the algorithm has no backtracking process. If the variables currently being considered are either true or false, the entire 2-SAT problem can be proved to be non-solvable (even if the previously assigned variables are not used). It is obvious that each variable will only affect the value of the expression that is related to the variable, so the unassigned variable must be independent of the previous assignment and can be considered separately, and the whole problem has a solution that needs to satisfy each block. Here's the code to solve the 2-sat problem:
1 struct_2_sat{2 intN;3vector<int> G[MAXN <<1];4 BOOLMARK[MAXN <<1];5 intS[MAXN <<1], C;6 BOOLDfsintx) {7 if(mark[x ^1])return 0;8 if(Mark[x])return 1;9MARK[X] =1;TenS[c++] =x; Onefor (I,0, G[x].size ()-1)if(!dfs (G[x][i]))return 0; A return 1; - } - voidInitintN) { the This->n =N; -for (I,0,2N1) g[i].clear (); -CLR (Mark,0); - } + //x = xval or y = yval - voidAdd_caluse (intXintXval,intYintyval) { +x = x *2+ xval, y = y *2+Yval; Ag[x ^1].PB (y), G[y ^1].PB (x); at } - BOOLsolve () { - for(inti =0; I <2N i + =2)if(!mark[i] &&!mark[i +1]){ -c =0; - if(!DFS (i)) { - while(C >0) Mark[s[--c]] =0; in if(!dfs (i +1))return 0; - } to } + return 1; - } the};
It is easy to see that the complexity of this algorithm is $o (n^2) $.
Graph theory $\cdot$2-sat problem