Today, learning the 2-sat problem, I found this example, knocked a bit, still better.
The 2-sat problem should be to reflect the logical relationship between some Boolean variables to an all-in-one graph (sometimes a graph). In the form of derivation, the edge is filled in the direction graph. Then, by determining the values of some variables, all the variables can conform to the logical relationship in test instructions. The trimming method is if Xi = True && Xj = False does not conform to test instructions, then if Xi = = True, then an edge is attached between XI = True and XJ = True so that when Xi = true, XJ = T is immediately determined. Rue In practice, a point Xi is always split into two points xi*2 and xi*2+1, where xi*2 indicates that when Xi is False, xi*2+1 indicates when Xi*2+1 is true. At the same time, in order to determine the true and false of Xi, and whether the value of Xi has been determined. Use a Boolean array mark to judge. If mark[xi*2] = = 1 Then the value of Xi is false, mark[xi*2+1] = = 1 Then the value of Xi is true. If mark[xi*2] = = 1 && mark[xi*2+1] = = 1 indicates that the previously determined variable is wrong. If mark[xi*2] = = 0 && mark[xi*2+1] = = 0, you need to start to determine the value of the variable. When determining the value of a variable, it is assumed to be false, and if it fails, it is assumed to be true. If it fails again, exit. Success is looking for the next indeterminate variable. Of course, after the failure, it is necessary to remove the mark from this period.
This problem code is as follows
1#include <cstdio>2#include <iostream>3#include <cstring>4#include <vector>5 #defineMAXN 1000096 #defineRep (i,j,k) for (int i = j; I <= K; i++)7 using namespacestd;8 9 intN, m, a[maxn] = {0}, s[maxn][2] = {0};Ten DoublePo; One A intRead () - { - ints =0, t =1;Charc =GetChar (); the while( !IsDigit (c)) { - if(c = ='-') T =-1; c =GetChar (); - } - while(IsDigit (c)) { +s = S *Ten+ C-'0'; c =GetChar (); - } + returnS *T; A } at - structtwo_sat{ - intN; -vector<int> q[maxn*2]; - ints[maxn*2], C; - BOOLmark[maxn*2]; in - voidInitintN) { to This-n =N; +Rep (I,0N2-1) q[i].clear (); -memset (Mark,0,sizeof(Mark)); the } * $ BOOLDfsintx)Panax Notoginseng { - if(mark[x^1] )return false; the if(Mark[x])return true; +S[c++] =x; AMARK[X] =1; the ints =q[x].size (); +Rep (I,0, S-1){ - if(!dfs (Q[x][i]))return false; $ } $ return true; - } - the BOOLSolve () - {Wuyi for(inti =0; I < n2; i + =2) the { - if(!mark[i] &&!mark[i^1] ){ Wuc =0; - if( !DFS (i)) { About while(C >0) Mark[s[--c]] =0; $ if(!dfs (i+1) )return false; - } - } - } A return true; + } the }; - $ Two_sat solver; the the BOOLTest () the { the solver.init (n); -Rep (I,0, M-1){ in if((a[s[i][0]] < PO && a[s[i][1]] < PO) | | (a[s[i][0]] >= po && a[s[i][1]] >=po)) the { thesolver.q[s[i][0]*2].push_back (s[i][1]*2+1); solver.q[s[i][0]*2+1].push_back (s[i][1]*2); Aboutsolver.q[s[i][1]*2].push_back (s[i][0]*2+1); solver.q[s[i][1]*2+1].push_back (s[i][0]*2); the the } the Else { +solver.q[s[i][0]*2+1].push_back (s[i][1]*2); -solver.q[s[i][1]*2+1].push_back (s[i][0]*2); the }Bayi } the the BOOLOK =solver.solve (); - if(OK) { -Rep (I,0, N-1){ the if(A[i] <PO) { the if(solver.mark[i*2]) printf ("b\n"); the Elseprintf"c\n"); the } - Else { the if(solver.mark[i*2]) printf ("a\n"); the Elseprintf"c\n"); the }94 } the } the returnOK; the }98 About intMain () - {101 while(SCANF ("%d%d", &n,&m) = =2&& N &&m) {102 intsum =0;103Rep (I,0, N-1) {104A[i] =read (); theSum + =A[i];106 }107PO =1.0* Sum/N;108Rep (I,0, M-1){109Rep (J,0,1) theS[I][J] = Read (), s[i][j]--;111 } the if( !test ()) {113cout<<"No solution\n"; the } the } the return 0;117}
Uva 1391 (LA 3713) Astronauts (2-sat problem)