바닥 퍼즐

POJ

문제의 의미가있다 \ (N \) 변수 \ (X_1-x_n의 \) 의 가능한 값을 각각 0 또는 변수가 주어진 1 \ (M \) 방정식 번째 형식의 각 방정식 \ (X_a \ ) \ (OP \) \ (X_b = C \) 여기서 \는 (A, B \) 두 변수의 개수 \ (C는 \) 수가 0. 1이다 \ (OP는 \) 된다 (그리고 \ \ ) , \ (또는 \) , \ (XOR \) 세 비트 동작의 모든 방정식에 해당하는 각 변수 등을위한 유효한 할당이 있는지 여부를 묻는다.. \ (N - <= 1000, m <= 10. 6 ^ . \)

분석 : \ (토 -2- \) 문제는, 첫째로 변환 \ (토 -2- \) . 노드의 형태로 제공 \ (A는 \) 대표 \ (X_a는 \) 0, 노드 값 \ (a + n \) 표현 (\ x_a \) 의 값을 1 :

\ (A \) \ (및 \) \ (B = 0 \) 다음 \ (x_a = 1 \)\는 (X_b는 \) 해야 \ (= 0 \) 에도 관한 에지 \ ((a + N-, B) \) ..이 생각 노트와 같은 다른 경우가 : 심지어 인연의 조건을 만족시킬 수있는 것은 : "P 경우, q는해야합니다".

도가 만났 소리를 나타내는 두 글자의 후 내장 \ (Tarjan \) 노드가있는 경우, \ (나는 \) , \ (나는 \)(\가 + N I) \ 같은 강력하게 연결 구성 요소에 속하는를, 다음 유효한 할당은 없다 가.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=1005;
const int M=4e6+5;
int tot,head[N],nxt[M],to[M];
int tim,top,num,dfn[N],low[N],st[M],color[N];
inline void add(int a,int b){nxt[++tot]=head[a];head[a]=tot;to[tot]=b;}
inline void tarjan(int u){
    dfn[u]=low[u]=++tim;st[++top]=u;
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!color[v])low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        color[u]=++num;
        while(st[top]!=u){
            color[st[top]]=num;
            --top;
        }
        --top;
    }
}
int main(){
    int n=read(),m=read();
    for(int i=1;i<=m;++i){
        int a=read(),b=read(),c=read();
        ++a;++b;string s;cin>>s;
        if(s[0]=='A'){
            if(c==0)add(a+n,b),add(b+n,a);
            else add(a,a+n),add(b,b+n);
        }
        else if(s[0]=='O'){
            if(c==0)add(a+n,a),add(b+n,b);
            else add(a,b+n),add(b,a+n);
        }
        else if(s[0]=='X'){
            if(c==0){
                add(a,b);add(b,a);
                add(a+n,b+n);add(b+n,a+n);
            }
            else{
                add(a,b+n);add(b,a+n);
                add(a+n,b);add(b+n,a);
            }
        }
    }
    for(int i=1;i<=n*2;++i)if(!dfn[i])tarjan(i);
    for(int i=1;i<=n;++i)
        if(color[i]==color[i+n]){
            puts("NO");return 0;
        }
    puts("YES");
    return 0;
}

추천

출처www.cnblogs.com/PPXppx/p/11592627.html