パズルフロアのPMU - 3678(2 - 時間)

N変数とX1 X1〜XN XN、各変数の可能な値は0又は1です。

フォームの各式、M方程式所与  X- A O P X- B = C、Bが可変数であるXaopXb = C、Cは、数0又は1、OPは、3つのXORビット単位であり、又はありますA。

すべての式が真であるように、各変数への法的な割り当てがあるかどうかを確認して下さい。

入力形式

最初の行は二つの整数N及びMを含有します

次のM行、ABC三つの整数を含む各列、及びビット演算(AND、OR、XOR 1)。

出力フォーマット

出力、存在する場合、出力「YES」、そうでない場合は「NO」

データ範囲

1 N 1000年 1≤N≤1000、
1 M 10 6 1≤M≤106

サンプル入力:

4 4
0 1 1 AND 1 2 1 OR 3 2 0 AND 3 0 0 XOR 

出力例:

YES


アイデア:質問の意味、問題は2-SATの問題であり、変換演算子は、判断することができます

[x]は、することができるためではない([X]およびA [Y])のために '<実施実現、X、[x]は、偶数<X、X>通信エッジを介してX Edgeのできない' を>あなたは '<Y、X及び>達成され、二つのエッジ<X接続する必要がある[X]または[Y]が ' Y>とを<Y'、X>から<X、Y>' 2つのエッジを接続するために必要実現

以下のためのように、または、XORの3つの動作は以下のとおりです。

そして、操作:

及びb = 0:= 1である場合、B = 0が満たさなければならない; B = 1なら、すなわち、= 0が満たさなければならない:<1、B、 0>、<B、1、 0>
A = Bと1:A = 1、B = 1、すなわち:<A、0、1、。>、<B、0、B ,. 1>
又は操作:

またはb = 0の場合:= 0、B = 0、すなわち<,. 1、A、0>、<B ,. 1、B、0> 
。AまたはB = 1:= 0がある場合、そこ必要満たすB = 1; b = 0であれば、= 0、つまり存在満たさなければならない:<A、0、B ,. 1>、<B、0、1、。>
XOR演算を:

XOR b = 0で、以下の4例:
= 0の場合、B = 0が満たさなければならない、すなわち:<0、B、 0>
B = 0の場合、すなわち、= 0が満たさなければなりません。 <B、0、0 >
= 1の場合、すなわち、B = 1、が満たさなければならない:<1、B 1>を
、B = 1の場合、すなわち、= 1が満たさなければならない:<B、1 、,. 1>
A = B XOR 1、以下4例:
<0、B = 0の場合、B = 1、すなわちそこに満足しなければならない 1>
= 0 bであれば、満たされなければなりません= 1、すなわち、<B、0、 1>
B = 0、すなわち満足しなければならない= 1であれば、そこ:<1、B、 0>
B = 1の場合、次に、すなわち、= 0が満たさなければなりません。 <B、1、 0>

#include <iostreamの> 
する#include <cstdioを> 
する#include <アルゴリズム> 
の#include <CStringの> 使用して名前空間STD。
#defineデバッグ(x)はcoutの<< << X << "\ n"を"バグ性交"。
#define IOS IOS :: sync_with_stdio(偽)、cin.tie(0)、cout.tie(0)
 CONST INT MAXN = 4E5 + 7 
typedefの長い長いLL。INTのN、M。構造体の
{ INT 、NXTに、
} E [MAXN]。int型のヘッド[MAXN]、TOT;
無効アドオン(int型のuを、

   




    

++ TOT] .TO = V。
    E [TOT] .nxt = 頭部[U]。
    ヘッド[U]は = TOTを、
} 

INT DFN [MAXN]、低[MAXN]、NUM、inStack [MAXN]。
INTのスタック[MAXN]、トップ、CNT、C [MAXN]。
ボイド tarjan(INT X){ 
    [X] DFN =低[X] = ++ NUM。
    [スタック ++トップ] = xを、inStack [X] = 以下のためにint型 ; I I = I =ヘッド[X] {E [I] .nxt)
         INT Y = E [I] .TO。
        もし(DFN [Y] == 0 ){ 
            tarjan(Y)。
            低[X] = 分(低[x]は、低[Y])。
        } そう であれば(inStack [Y]){ 
            低い[X] = 分(低[x]は、低[Y])。
        } 
    } 
    もし(低[X] == {[X] DFN)
        CNT ++ int型のZ;
        { 
            Zは = [top--スタック]。
            inStack [Z] = 
            C [Z] = CNT。
        } 一方(Z =!X)。
    } 
} int型(主

INT ARGC、チャー CONST * ARGV [])
{ 
    // CIN >> N >> M。
    scanf関数(" %d個の%のD "、&​​N、&M)。
    以下のためにint型私= 1 ; I <= M; iが++ ){
         int型、B、C。チャー STR [ 10 ]。
        // cinを>> A >> B >> C >> STR。
        scanf関数(" %D%D%D%S "、&​​、&B、&C、STR)。
        もし(STR [ 0 ] == ' A '
                (追加 +のN)。
                (B、B追加 + n)を。
            } { 
                追加(A + N、B)。
                (Bを追加 + N、A)。
            } 
        } そう であれば(STR [ 0 ] == ' O ' ){
             場合(Cの== 1 ){ 
                (B追加 + n)を。
                (B、追加 +のN)。
            } { 
                追加(A +N、A)。
                (B追加 + B、N)。
            } 
        } そう であれば(STR [ 0 ] == ' X ' ){
             場合(C == 1 ){ 
                (B追加 + n)を。
                (B、追加 +のN)。
                追加(A + N、B)。
                (Bを追加 + N、A)。
            } { 
                追加(A、B)。
                (B、A)を加えます。
                (A追加 + N、B + N)。
                (B追加、+ N A +N); 
            } 
        }     
    } 

    のためのint型 I = 0 ; iが<N + N; iが++ ){
         場合(!tarjan(I)DFN [I])。
    } 

    ブールフラグ= 1 以下のためにint型 i = 0 ; iがn <; iは++ ){
         もし(C [I] == C [iが+ N]){ 
            フラグ = 0 破ります; 
        } 
    } 

    もし(フラグ)プット(" YES " );
    プット(" NO " ); 

    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/DWVictor/p/11354998.html