This is also a magic graph creation question. This question fully reflects the nature of who is required for the 2-sat.
If you select a required method in a round, you need to connect an edge to the opposite point. That is, if you select a, you need to enter an edge a->'
In short, we need to constantly find contradictions.
The stickers are frustrating.Code
View code
# Include <stdio. h>
# Include < String . H>
# Include <vector>
# Include <algorithm>
Using Namespace STD;
Const Int Max = 20010 ;
Vector <Int > Edge [Max];
Int St [Max];
Int Dfn [Max], low [Max];
Int Top, btype, tdfn;
Int Belong [Max];
Bool INS [Max];
Void DFS ( Int S)
{
Int I, T;
Dfn [s] = low [s] = ++ tdfn;
INS [s] =True ;
St [++ top] = s;
For (I = 0 ; I <edge [s]. Size (); I ++)
{
T = edge [s] [I];
If (! Dfn [T])
{
DFS (t );
If (Low [T] <low [s]) low [s] = low [T];
}
Else If (INS [T] & dfn [T] <low [s]) low [s] = dfn [T];
}
If (Dfn [s] = low [s])
{
Btype ++;
Do
{
T = sT [top --];
INS [T] = False ;
Belong [T] = btype;
} While (T! = S );
}
}
Void SCC ( Int N)
{
Int I;
Top = btype = tdfn = 0 ;
Memset (INS, False , Sizeof (INS ));
Memset (dfn, 0 , Sizeof (Dfn ));
For (I = 1 ; I <= N; I ++)
If (! Dfn [I])
DFS (I );
}
Int Bob;
Int Alice [Max];
Int Main ()
{
Int I, J, K, T;
Int N, m;
Int A, B, cases = 1 ;
Scanf ( " % D " , & T );
While (T --)
{
Scanf (" % D " , & N, & M );
For (I = 0 ; I <= 2 * N; I ++)
Edge [I]. Clear ();
For (I = 1 ; I <= N; I ++)
{
Scanf ( " % D " , & Bob );
If (Bob = 1 )
{
Alice [I] = 1 ;
Alice [I + N] = 2 ;
}
If (Bob = 2 )
{
Alice [I] = 2 ;
Alice [I + N] = 3 ;
}
If (Bob = 3 )
{
Alice [I] = 3 ;
Alice [I + N] = 1 ;
}
}
For (I = 0 ; I <m; I ++)
{
Scanf ( " % D " , & A, & B, & K );
If (K = 1 )
{
If (Alice [a] = Alice [B])
{
Edge [A]. push_back (B + n );
Edge [B]. push_back (a + n );
}
If (Alice [a] = Alice [B + N])
{
Edge [A]. push_back (B );
Edge [B + N]. push_back (a + n );
}
If (Alice [A + N] = Alice [B])
{
Edge [A + N]. push_back (B + n );
Edge [B]. push_back ();
}
If (Alice [A + N] = Alice [B + N])
{
Edge [A + N]. push_back (B );
Edge [B + N]. push_back ();
}
}
If (K = 0 )
{
If (Alice [a]! = Alice [B])
{
Edge [A]. push_back (B + n );
Edge [B]. push_back (a + n );
}
If (Alice [a]! = Alice [B + N])
{
Edge [A]. push_back (B );
Edge [B + N]. push_back (a + n );
}
If (Alice [A + N]! = Alice [B])
{
Edge [A + N]. push_back (B + n );
Edge [B]. push_back ();
}
If (Alice [A + N]! = Alice [B + N])
{
Edge [A + N]. push_back (B );
Edge [B + N]. push_back ();
}
}
}
SCC ( 2 * N );
Int Flag = 1 ;
For (I = 1 ; I <= N; I ++)
{
If (Belong [I] = belong [I + N])
{
Flag = 0 ;
Break ;
}
}
If (FLAG) printf ( " Case # % d: Yes \ n " , Cases ++ );
Else Printf ( " Case # % d: NO \ n " , Cases ++ );
}
Return 0 ;
}