zoukankan      html  css  js  c++  java
  • Katu Puzzle POJ

    有N个变量X1X1~XNXN,每个变量的可能取值为0或1。

    给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三个位运算之一。

    求是否存在对每个变量的合法赋值,使所有算式都成立。

    输入格式

    第一行包含两个整数N和M。

    接下来M行,每行包含三个整数a b c,以及一个位运算(AND,OR,XOR中的一个)。

    输出格式

    输出结果,如果存在,输出“YES”,否则输出“NO”

    数据范围

    1N10001≤N≤1000,
    1M1061≤M≤106

    输入样例:

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

    输出样例:

    YES


    思路:根据题意,该题是一个 2-SAT 问题,将操作符进行转换,进行判定即可

    对于 A[x],可以通过连边 <x',x> 实现,NOT A[x],可以通过连边 <x,x'> 来实现,对于 NOT(A[x] AND A[y]) 需要连两条边 <x, y'> 和 <y, x'> 来实现,对于 A[x] OR A[y] 需要连两条边 <x', y> 和 <y', x> 来实现

    故对于 and、or、xor 三种运算有:

    and 运算:

    a and b = 0 时:若 a=1,则必定满足 b=0;若 b=1,则必定满足 a=0,即:<a,1,b,0>、<b,1,a,0>
    a and b = 1 时:a=1 且 b=1,即:<a,0,a,1>、<b,0,b,1>
    or 运算:

    a or b = 0 时:a = 0 且 b = 0,即:<a,1,a,0>、<b,1,b,0> 
    a or b = 1 时:若 a=0,则必定满足 b=1;若 b=0,则必定满足 a=0,即:<a,0,b,1>、<b,0,a,1>
    xor 运算:

    a xor b = 0 时,有以下四种情况:
    若 a = 0,则必定满足 b = 0,即:<a,0,b,0>
    若 b = 0,则必定满足 a = 0,即:<b,0,a,0>
    若 a = 1,则必定满足 b = 1,即:<a,1,b,1>
    若 b = 1,则必定满足 a = 1,即:<b,1,a,1>
    a xor b = 1 时,有以下四种情况:
    若 a = 0,则必定满足 b = 1,即:<a,0,b,1>
    若 b = 0,则必定满足 a = 1,即:<b,0,a,1>
    若 a = 1,则必定满足 b = 0,即:<a,1,b,0>
    若 b = 1,则必定满足 a = 0,即:<b,1,a,0>

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    #define debug(x) cout << "fuck bug " << x << "
    ";
    #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    const int maxn = 4e5 + 7;
    typedef long long ll;
    
    int n,m;
    
    struct edge
    {
        int to,nxt;
    }e[maxn];
    
    int head[maxn],tot;
    void add(int u ,int v){
        e[++tot].to = v;
        e[tot].nxt = head[u];
        head[u] = tot;
    }
    
    int dfn[maxn],low[maxn],num,inStack[maxn];
    int stack[maxn],top,cnt,C[maxn];
    void tarjan(int x) {
        dfn[x] = low[x] = ++num;
        stack[++top] = x; inStack[x] = true;
        for (int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if (dfn[y] == 0) {
                tarjan(y);
                low[x] = min(low[x], low[y]);
            } else if (inStack[y]) {
                low[x] = min(low[x], low[y]);
            }
        }
        if (low[x] == dfn[x]) {
            cnt++;
            int z;
            do {
                z = stack[top--];
                inStack[z] = false;
                C[z] = cnt;
            } while (z != x);
        }
    }
    
    int main(int argc, char const *argv[])
    {
        //cin >> n >> m;
        scanf("%d %d",&n,&m);
        for(int i = 1;i <= m ; i ++){
            int a , b , c ; char str[10];
            //cin >> a >> b >> c >> str;
            scanf("%d %d %d %s",&a,&b,&c,str);
            if(str[0] == 'A'){
                if(c == 1){
                    add(a,a+n);
                    add(b,b+n);
                }else{
                    add(a+n,b);
                    add(b+n,a);
                }
            }else if(str[0] == 'O'){
                if(c == 1){
                    add(a,b+n);
                    add(b,a+n);
                }else{
                    add(a+n,a);
                    add(b+n,b);
                }
            }else if(str[0] == 'X'){
                if(c == 1){
                    add(a,b+n);
                    add(b,a+n);
                    add(a+n,b);
                    add(b+n,a);
                }else{
                    add(a,b);
                    add(b,a);
                    add(a+n,b+n);
                    add(b+n,a+n);
                }
            }    
        }
    
        for(int i = 0;i < n + n; i++){
            if(!dfn[i]) tarjan(i); 
        }
    
        bool flag=1;
        for(int i = 0;i < n ;i ++){
            if(C[i] == C[i + n]) {
                flag = 0;
                break;
            }
        }
    
        if(flag) puts("YES");
        else puts("NO");
    
        return 0;
    }
  • 相关阅读:
    关于这个 blog
    P6499 [COCI2016-2017#2] Burza 题解
    CF1172F Nauuo and Bug 题解
    CF1479D Odd Mineral Resource 题解
    CF1442E Black, White and Grey Tree 题解
    CF1442D Sum 题解
    CF1025D Recovering BST 题解
    CF1056E Check Transcription 题解
    CF1025F Disjoint Triangles 题解
    红包算法的PHP实现
  • 原文地址:https://www.cnblogs.com/DWVictor/p/11354998.html
Copyright © 2011-2022 走看看