I have read 2-SAT papers over the past few days, and I have also made some related questions.
The so-called 2-SAT is A pair of contradictions, that is, they cannot get together, such as family A and B. Family A has a0 and a1, and family B has b0 and b1. Now, each family is required to be present in A group. If there are no constraints, we can have four options to meet the conditions, namely (a0, b0) (a0, b1), (a1, b0), (a1, b1 ). However, if we give a constraint that a1 and b1 cannot attend at the same time, it is equivalent to a team that is not compatible with each other. If so, we can choose less, although this option is reduced (a1, b1), it actually hides a constraint in terms of conditions, that is, if I select a1, in type B, I have no choice, that is, it can only be b0. After b0 is selected, the chain constraint associated with it will be brought out. In this case, the fate of a1 and b0 is the same, that is, either one is selected or the other is selected.
When we get a set of contradictions, we can change the fate together and determine whether there is a feasible solution by seeking for a strongly connected component.
In addition, I have attached a detailed link to this question, so I must have a better understanding of 2-SAT.
Http://hi.baidu.com/fhnstephen/blog/item/7c889883900a53db9023d95d.html
By the way, I attached my code (using Tarjan of Jilin University)
# Include <cmath>
# Include <stdio. h>
# Include <string. h>
# Include <set>
# Include <queue>
# Include <vector>
# Include <iostream>
Using namespace std;
# Define V 6010
Int n, m;
/* ===================================================== =============== */
| Tarjan Strongly Connected Component
| INIT: vec [] is an adjacent table; stop, cnt, scnt is set to 0; pre [] is set to-1;
| CALL: for (I = 0; I <n; ++ I) if (-1 = pre [I]) tarjan (I, n );
/* ===================================================== =============== */
Vector <int> vec [V];
Int id [V], pre [V], low [V], s [V], stop, cnt, scnt;
Void tarjan (int v, int n) // vertex: 0 ~ N-1
{
Int t, minc = low [v] = pre [v] = cnt ++;
Vector <int>: iterator pv;
S [stop ++] = v;
For (pv = vec [v]. begin (); pv! = Vec [v]. end (); ++ pv ){
If (-1 = pre [* pv]) tarjan (* pv, n );
If (low [* pv] <minc) minc = low [* pv];
}
If (minc <low [v]) {
Low [v] = minc; return;
}
Do {
Id [t = s [-- stop] = scnt; low [t] = n;
} While (t! = V );
+ + Scnt; // Number of strongly connected components
}
Void addedge (int s, int e)
{
// G [s]. push_back (e );
// RG [e]. push_back (s );
VEC [s]. push_back (E );
}
Void Init () // initialization Diagram
{
Int I, j, A, B, Res;
Memset (PRE,-1, sizeof (pre ));
Stop = CNT = SCNT = 0;
Char ch [5];
For (I = 0; I <n; ++ I)
{
VEC [I]. Clear ();
// G [I]. Clear ();
// RG [I]. Clear ();
}
While (M --)
{
Scanf ("% d % s", & A, & B, & res, & Ch );
A <= 1; B <= 1;
A ++; B ++;
If (CH [0] = 'A ')
{
If (RES = 1)
{
Addedge (A-1, );
Addedge (B-1, B );
}
Else
{
Addedge (a, B-1 );
Addedge (B, A-1 );
}
}
Else if (ch [0] = 'O ')
{
If (res = 1)
{
Addedge (A-1, B );
Addedge (B-1, );
}
Else
{
Addedge (a, A-1 );
Addedge (B, B-1 );
}
}
Else
{
If (res = 0)
{
Addedge (a, B );
Addedge (B, );
Addedge (A-1, B-1 );
Addedge (B-1, A-1 );
}
Else
{
Addedge (A-1, B );
Addedge (B, A-1 );
Addedge (a, B-1 );
Addedge (B-1, );
}
}
}
}
Bool Judge ()
{
Int I;
For (I = 0; I <n; ++ I)
If (-1 = pre [I]) tarjan (I, n );
For (I = 0; I <n; I + = 2)
If (id [I] = id [I + 1])
Return false;
Return true;
}
Void Solve ()
{
Int I, j;
N = n + n;
Init ();
If (Judge () = false)
Printf ("NO/n ");
Else
Printf ("YES/n ");
}
Int main ()
{
While (scanf ("% d", & n, & m )! = EOF)
Solve ();
Return 0;
}